Init进程是Android系统中第一个用户空间进程,承担着整个系统的初始化重任。本章将深入剖析Init进程的实现原理,包括其启动流程、RC脚本解析、属性服务、SELinux策略加载等核心机制。通过与Linux传统init、iOS的launchd、鸿蒙OS的init对比,读者将全面理解Android独特的系统启动架构。
当Linux内核完成自身初始化后,会启动第一个用户空间进程——Init进程(PID=1)。Android的Init进程实现位于system/core/init/目录,其入口函数是main()。内核通过run_init_process()调用/init二进制文件,这是ramdisk中的第一个程序。
内核到用户空间的转换
kernel_init() -> run_init_process("/init") -> execve("/init")
内核在kernel_init()函数中按以下顺序尝试启动init:
ramdisk_execute_command(通常是/init)/sbin/init/etc/init/bin/init/bin/sh(紧急模式)Android将init放在ramdisk根目录,确保第一个被找到。内核传递的环境变量极其有限:
HOME=/TERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binInit进程的生命周期分为两个阶段:
First Stage Init First Stage Init在ramdisk环境中运行,使用静态链接的最小化二进制文件,主要任务是准备真正的根文件系统:
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755")mount("devpts", "/dev/pts", "devpts", 0, NULL)支持伪终端mount("proc", "/proc", "proc", 0, "hidepid=2")增强安全性mount("sysfs", "/sys", "sysfs", 0, NULL)导出内核对象/dev/null、/dev/zero、/dev/full等基础设备/dev/kmsg用于内核日志(主设备号1,次设备号11)/dev/random、/dev/urandom用于随机数(主设备号1,次设备号8/9)/dev/ptmx伪终端主设备(主设备号5,次设备号2)mknod()系统调用创建,设置权限0666或0600android::base::InitLogging()设置日志系统/dev/kmsg/system(只读)/vendor(只读)SelinuxInitialize()加载编译后的策略u:r:init:s0/system/etc/selinux/plat_sepolicy.cil加载平台策略/vendor/etc/selinux/vendor_sepolicy.cil厂商策略selinux_android_load_policy()加载到内核execv("/system/bin/init", argv)重新执行自身--second-stage参数标识/dev/kmsg)Second Stage Init Second Stage Init从真正的系统分区运行,拥有完整的库支持和更丰富的功能:
/dev/__properties__)/dev/socket/property_service)/default.prop(ramdisk中的属性)/system/build.prop(系统属性)/vendor/build.prop(厂商属性)/product/build.prop(产品属性)/odm/build.prop(ODM属性)/init.rc(主配置文件)/system/etc/init/(系统服务)/vendor/etc/init/(厂商服务)/odm/etc/init/(ODM服务)/dev/socket/init)关键环境变量设置
PATH=/system/bin:/system/xbin:/vendor/bin:/odm/bin
LD_LIBRARY_PATH=/system/lib64:/vendor/lib64:/odm/lib64
ANDROID_ROOT=/system
ANDROID_DATA=/data
ANDROID_STORAGE=/storage
ANDROID_RUNTIME_ROOT=/apex/com.android.runtime
ANDROID_TZDATA_ROOT=/apex/com.android.tzdata
ANDROID_ART_ROOT=/apex/com.android.art
BOOTCLASSPATH=/apex/com.android.runtime/javalib/core-oj.jar:...
Init进程使用精心设计的数据结构管理系统启动,这些结构体现了Android对启动过程的细粒度控制:
Action(动作)
struct Action {
std::string name;
std::vector<Command> commands;
std::map<std::string, std::string> property_triggers;
std::string event_trigger;
bool oneshot;
int trigger_order; // 触发优先级
// 执行状态管理
size_t current_command;
bool ExecuteOneCommand();
bool CheckPropertyTriggers();
// 触发器管理
std::set<std::string> required_property_contexts;
bool TriggersEqual(const Action& other) const;
// 执行控制
std::chrono::steady_clock::time_point last_command_time;
std::optional<std::chrono::milliseconds> command_timeout;
}
Action的关键特性:
boot)或属性触发器(如property:sys.boot_completed=1)oneshot标记的Action只执行一次Service(服务)
struct Service {
std::string name;
unsigned flags; // SVC_RUNNING, SVC_DISABLED, SVC_RESTARTING等
pid_t pid;
std::vector<std::string> args;
std::vector<Option> options;
// 服务控制
int crash_count;
time_t time_started;
time_t time_crashed;
std::chrono::seconds restart_period = 5s; // 重启间隔
std::optional<std::chrono::seconds> timeout_period; // 启动超时
// 进程管理
std::optional<std::string> console; // 控制台设备
std::optional<bool> sigstop; // 启动后是否暂停
std::vector<std::pair<int, rlimit>> rlimits; // 资源限制
std::vector<std::string> writepid_files; // PID文件路径
// 安全上下文
std::string seclabel; // SELinux标签
std::vector<uid_t> supp_gids; // 补充组ID
CapSet capabilities; // Linux capabilities
std::optional<std::vector<std::string>> updatable; // APEX更新
// 命名空间隔离
unsigned namespace_flags; // CLONE_NEWPID, CLONE_NEWNET等
std::vector<std::string> namespaces_to_enter; // 进入已存在的namespace
// cgroup和调度
std::map<std::string, std::string> cgroup_paths;
int oom_score_adjust = -1000; // OOM killer调整值
int priority = 0; // nice值
struct sched_param scheduling_param; // 实时调度参数
// 服务依赖
std::set<std::string> before_services; // 必须在这些服务前启动
std::set<std::string> after_services; // 必须在这些服务后启动
// 关键服务处理
bool is_critical = false; // 崩溃是否触发重启
std::vector<std::string> critical_services_to_restart;
}
Service的高级特性:
Property(属性)
// 属性存储结构
struct prop_info {
atomic_uint_least32_t serial; // 版本号,用于检测变化
char value[PROP_VALUE_MAX]; // 属性值(92字节)
char name[PROP_NAME_MAX]; // 属性名(32字节)
};
// 属性区域管理
struct prop_area {
uint32_t bytes_used;
atomic_uint_least32_t serial; // 全局版本号
uint32_t magic; // 0x504f5250 ('PROP')
uint32_t version; // 当前版本号
uint32_t reserved[4];
char data[0]; // 实际属性数据
};
// 属性节点(Trie树结构)
struct prop_bt {
uint32_t namelen; // 名称长度
uint32_t proplen; // 属性数量
uint32_t children; // 子节点偏移
uint32_t props; // 属性列表偏移
char name[0]; // 节点名称
};
// 属性上下文映射
struct prop_context {
const char* name_prefix; // 属性前缀
const char* context; // SELinux上下文
bool exact_match; // 是否精确匹配
};
系统属性的高级特性:
mmap映射到所有进程,零拷贝访问serial字段检测属性变化,避免轮询命令管理器(CommandManager)
class BuiltinFunctionMap {
std::map<std::string, BuiltinFunction> functions_;
// 注册的内置命令
void RegisterBuiltinFunctions() {
// 文件系统操作
Register("chmod", do_chmod);
Register("chown", do_chown);
Register("copy", do_copy);
Register("mkdir", do_mkdir);
Register("mount", do_mount);
Register("umount", do_umount);
Register("symlink", do_symlink);
Register("rm", do_rm);
Register("rmdir", do_rmdir);
Register("write", do_write);
// 服务控制
Register("class_start", do_class_start);
Register("class_stop", do_class_stop);
Register("class_reset", do_class_reset);
Register("start", do_start);
Register("stop", do_stop);
Register("restart", do_restart);
Register("enable", do_enable);
// 属性操作
Register("setprop", do_setprop);
Register("getprop", do_getprop);
Register("wait_for_prop", do_wait_for_prop);
// 进程执行
Register("exec", do_exec);
Register("exec_start", do_exec_start);
Register("exec_background", do_exec_background);
// 触发器管理
Register("trigger", do_trigger);
// 系统控制
Register("bootchart", do_bootchart);
Register("init_user0", do_init_user0);
Register("installkey", do_installkey);
Register("load_persist_props", do_load_persist_props);
// 网络配置
Register("hostname", do_hostname);
Register("domainname", do_domainname);
Register("ifup", do_ifup);
// 安全相关
Register("restorecon", do_restorecon);
Register("restorecon_recursive", do_restorecon_recursive);
Register("setrlimit", do_setrlimit);
Register("swapon_all", do_swapon_all);
// 日志和调试
Register("loglevel", do_loglevel);
Register("mark_post_data", do_mark_post_data);
}
// 命令执行包装
Result<Success> Execute(const std::string& name,
const std::vector<std::string>& args) {
auto it = functions_.find(name);
if (it == functions_.end()) {
return Error() << "Unknown command: " << name;
}
return it->second(args);
}
};
命令系统的设计特点:
Result<T>类型安全地返回错误exec_background等命令支持非阻塞执行Init进程的主循环采用高效的epoll机制,这是Android系统响应性的基础。与传统的select/poll相比,epoll在大量文件描述符场景下性能更优:
事件源类型 Init进程监听的事件源包括:
/dev/socket/property_service)/dev/socket/init接收如ctl.start等命令)Epoll架构实现
class Epoll {
private:
int epoll_fd_;
std::map<int, std::function<void()>> handlers_;
public:
void Open() {
// 创建epoll实例,EPOLL_CLOEXEC防止fd泄露到子进程
epoll_fd_ = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd_ == -1) {
PLOG(FATAL) << "epoll_create1 failed";
}
// 注册信号处理(使用signalfd)
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGTERM);
signal_fd_ = signalfd(-1, &mask, SFD_CLOEXEC);
RegisterHandler(signal_fd_, HandleSignals);
// 注册属性服务
property_fd_ = CreatePropertySocket();
RegisterHandler(property_fd_, HandlePropertySet);
// 注册控制消息
init_fd_ = CreateInitSocket();
RegisterHandler(init_fd_, HandleInitSocket);
// 注册keychord(组合键)
keychord_fd_ = OpenKeychordDevice();
if (keychord_fd_ >= 0) {
RegisterHandler(keychord_fd_, HandleKeychord);
}
}
void RegisterHandler(int fd, std::function<void()> handler) {
epoll_event ev = {};
ev.events = EPOLLIN; // 监听可读事件
ev.data.fd = fd;
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
PLOG(ERROR) << "Failed to add fd " << fd << " to epoll";
return;
}
handlers_[fd] = std::move(handler);
}
std::optional<std::function<void()>> Wait(
std::optional<std::chrono::milliseconds> timeout) {
epoll_event events[32];
int timeout_ms = -1;
if (timeout.has_value()) {
timeout_ms = timeout->count();
}
int nr = epoll_wait(epoll_fd_, events,
arraysize(events), timeout_ms);
if (nr == -1) {
PLOG(ERROR) << "epoll_wait failed";
return std::nullopt;
}
for (int i = 0; i < nr; i++) {
auto it = handlers_.find(events[i].data.fd);
if (it != handlers_.end()) {
return it->second;
}
}
return std::nullopt;
}
};
主循环实现
int main() {
// ... 初始化代码 ...
while (true) {
// 1. 执行待处理的Actions
if (!ActionQueue.empty()) {
auto action = ActionQueue.front();
action->ExecuteOneCommand();
if (action->IsCompleted()) {
ActionQueue.pop();
}
}
// 2. 检查需要重启的服务
for (auto& service : ServiceList) {
if (service.flags & SVC_RESTARTING) {
if (CurrentTime() > service.time_crashed +
service.restart_period) {
service.Start();
}
}
}
// 3. 计算超时时间
int timeout = -1; // 默认无限等待
if (!ActionQueue.empty()) {
timeout = 0; // 有待处理命令,立即返回
} else if (HasRestartingServices()) {
timeout = CalculateRestartTimeout();
}
// 4. 等待事件
epoll_event events[32];
int nr = epoll_wait(epoll_fd, events, 32, timeout);
// 5. 处理事件
for (int i = 0; i < nr; i++) {
auto handler = handlers_[events[i].data.fd];
handler();
}
}
}
信号处理机制
void HandleSignals() {
signalfd_siginfo info;
read(signal_fd, &info, sizeof(info));
switch (info.ssi_signo) {
case SIGCHLD:
ReapChildren();
break;
case SIGTERM:
case SIGINT:
HandleShutdown();
break;
case SIGUSR1:
HandleBootchart();
break;
}
}
void ReapChildren() {
while (true) {
int status;
pid_t pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0) break;
Service* service = FindServiceByPid(pid);
if (service) {
service->Reap(status);
if (service->flags & SVC_CRITICAL) {
// 关键服务崩溃,可能触发重启
HandleCriticalCrash(service);
}
}
}
}
Linux传统init(SysV/systemd)
SysV init特点:
update-rc.d或chkconfig管理服务systemd特点:
Android init对比:
iOS launchd
架构特点:
与Android init对比:
iOS launchd plist:
<dict>
<key>Label</key>
<string>com.apple.service</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/service</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
Android RC:
service apple_service /system/bin/service
class core
user system
group system
权限模型差异:
鸿蒙OS init
分布式特性:
与Android对比:
distributed_service标签支持跨设备配置文件对比:
// 鸿蒙服务配置
{
"services": [{
"name": "distributed_service",
"path": "/system/bin/d_service",
"distributed": true,
"capability": ["ohos.permission.DISTRIBUTED_DATA"],
"devices": ["phone", "tablet", "tv"]
}]
}
Android RC(Run Commands)脚本采用自定义的领域特定语言(DSL),主要包含四种语句类型:
Action定义
on <trigger> [&& <trigger>]*
<command>
<command>
...
完整的Action示例
# 早期初始化
on early-init
start ueventd
mkdir /mnt/vendor/persist 0771 root system
# 属性触发器
on property:sys.boot_completed=1
setprop sys.runtime.firstboot.end ${ro.runtime.firstboot.end}
exec_background - system system -- /system/bin/bootstat --record_boot_complete
# 多条件触发器
on property:vold.decrypt=trigger_restart_framework && property:ro.crypto.type=file
class_start main
class_start late_start
Service定义
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
完整的Service示例
# 基础服务示例
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart apexd
onrestart restart audioserver
onrestart restart gatekeeperd
onrestart class_restart main
writepid /dev/cpuset/system-background/tasks
# 厂商服务示例(小米)
service mi_thermald /system/bin/mi_thermald
class main
user system
group system
capabilities SYS_NICE NET_ADMIN
socket mi_thermald stream 0660 system system
Import语句
# 静态导入
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.${ro.zygote}.rc
# 动态导入(基于属性)
import /init.recovery.${ro.hardware}.rc
触发器类型详解
启动阶段触发器:
early-init:最早的初始化阶段,SELinux尚未加载init:基础文件系统已挂载late-init:所有init.*触发器完成后boot:/data分区已挂载,加密状态确定post-fs:/system挂载后立即执行post-fs-data:/data挂载并解密后执行zygote-start:在启动zygote前执行early-boot:boot完成后的早期阶段charger:充电模式下的特殊触发器属性触发器:
# 精确匹配
on property:persist.sys.language=zh-CN
setprop persist.sys.locale zh-CN
# 通配符匹配
on property:sys.boot_from_charger_mode=1
trigger late-init
# 多属性组合
on property:ro.crypto.state=encrypted && property:ro.crypto.type=file
start vold_decrypt
自定义触发器:
# 定义触发器
on enable-logging
start logd
start logd-reinit
# 触发自定义触发器
on boot
trigger enable-logging
Init进程使用ActionParser、ServiceParser等类解析RC文件:
解析器架构
class Parser {
std::map<std::string, std::unique_ptr<SectionParser>> parsers_;
void AddSectionParser(const std::string& name,
std::unique_ptr<SectionParser> parser) {
parsers_[name] = std::move(parser);
}
void ParseData(const std::string& data) {
Tokenizer tokenizer(data);
while (tokenizer.HasMore()) {
auto tokens = tokenizer.GetLine();
if (IsSectionStart(tokens[0])) {
current_parser_ = parsers_[tokens[0]];
}
current_parser_->ParseLine(tokens);
}
}
};
解析流程
// 将文本分解为Token,处理引号、转义字符
std::vector<std::string> Tokenizer::GetLine() {
// 跳过空白和注释
SkipWhitespace();
if (current_ == '#') SkipToNextLine();
// 解析token
while (!IsEndOfLine()) {
if (current_ == '"') {
tokens.push_back(ParseQuotedString());
} else {
tokens.push_back(ParseWord());
}
}
}
class ActionParser : public SectionParser {
void ParseSection(std::vector<std::string>& args) {
// "on" <trigger> [&& <trigger>]*
auto action = std::make_unique<Action>();
for (size_t i = 1; i < args.size(); i++) {
if (args[i] == "&&") continue;
action->AddTrigger(args[i]);
}
}
void ParseLine(std::vector<std::string>& args) {
// 解析命令
auto cmd = Command(args[0], args.begin() + 1, args.end());
current_action_->AddCommand(cmd);
}
};
bool Service::ParseLine(const std::vector<std::string>& args) {
static const OptionParserMap option_parsers = {
{"class", ParseClass},
{"user", ParseUser},
{"group", ParseGroup},
{"capabilities", ParseCapabilities},
{"seclabel", ParseSeclabel},
{"oneshot", ParseOneshot},
{"disabled", ParseDisabled},
// ... 更多选项
};
auto parser = option_parsers.find(args[0]);
if (parser == option_parsers.end()) {
return Error("Invalid option: " + args[0]);
}
return parser->second(args);
}
// 条件导入 if (android::base::GetBoolProperty(“ro.debuggable”, false)) { ParseConfig(“/system/etc/init/debug.rc”); }
**解析优化**
- 预编译的二进制格式(.rcb文件)
- 缓存解析结果避免重复解析
- 并行解析多个RC文件
- 增量解析支持动态加载
### 4.2.3 系统属性服务
Android的Property Service提供了一个全局的键值对存储系统:
**属性分类**
- `ro.*`:只读属性,启动后不可修改
- `persist.*`:持久化属性,重启后保留
- `sys.*`:系统控制属性
- `debug.*`:调试属性
**实现机制**
1. 属性存储在共享内存区域(`/dev/__properties__`)
2. 通过Unix域套接字`/dev/socket/property_service`接收设置请求
3. Init进程验证权限后更新共享内存
4. 通过`property_changed`触发器通知监听者
**访问控制**
- SELinux上下文检查
- UID/GID权限验证
- 属性前缀白名单
### 4.2.4 厂商定制扩展
各厂商在RC脚本中添加了大量定制:
**小米MIUI**
- 添加`on property:ro.miui.version`触发器
- 自定义`mi_thermald`温控服务
- 扩展`persist.sys.miui.*`属性族
**OPPO ColorOS**
- `oplus_init`阶段用于厂商服务初始化
- 自定义`oplusreserve`分区挂载
- AI调度相关属性配置
**华为EMUI**
- `hw_init`触发器族
- 分布式能力相关服务配置
- 安全增强属性设置
## 4.3 SELinux策略加载
### 4.3.1 Android中的SELinux
SELinux(Security-Enhanced Linux)为Android提供了强制访问控制(MAC)机制。与传统Linux发行版不同,Android对SELinux进行了深度定制:
**Android SELinux特点**
- 精简的策略集,专注于应用隔离
- 与UID/GID权限模型协同工作
- 支持动态策略更新(部分场景)
- 厂商可扩展的策略框架
**策略组成**
1. **平台策略**(Platform Policy):AOSP提供的基础策略
2. **厂商策略**(Vendor Policy):设备制造商添加的策略
3. **ODM策略**(ODM Policy):设备定制商的策略
### 4.3.2 策略加载流程
Init进程负责在启动早期加载SELinux策略:
**First Stage Init中的加载**
关键函数调用链
SelinuxInitialize() → LoadPolicy() → security_load_policy()/system/etc/selinux/, /vendor/etc/selinux/策略编译过程
libsepol合并策略/sys/fs/selinux/load加载到内核SELinux上下文格式:user:role:type:sensitivity[:categories]
Init进程的上下文转换
u:r:kernel:s0u:r:init:s0文件上下文恢复
Init进程使用restorecon恢复文件的SELinux标签:
/file_contexts定义文件标签规则iOS沙箱
鸿蒙安全架构
Linux AppArmor
Android通过多种技术实现服务的并行启动:
异步服务启动
class_start批量启动同类服务late_init阶段依赖管理优化
service critical_service /system/bin/critical
class core
priority -20
service normal_service /system/bin/normal
class late_start
after critical_service
I/O优化
mmap减少内存拷贝内存优化
CPU调度优化
高通Quick Boot
联发科Fast Boot
三星优化
samsung_init阶段bootchart
systrace
厂商工具
miui_boottime_analyzeroplus_boot_trackerhw_bootprof本章深入剖析了Android Init进程的核心机制:
关键要点:
1. Init进程的PID为什么必须是1?
2. 解释Android属性的命名规则和访问权限机制
3. RC脚本中的class和disabled选项有什么作用?
4. First Stage Init为什么要以最小化方式实现?
5. 设计一个RC脚本实现以下需求:当检测到调试版本时自动启动性能分析服务,但在用户版本中禁用
6. 分析以下场景:某个关键服务反复崩溃重启,Init进程会如何处理?如何优化?