split first stage init into a separate executable
In the future, systems with dm-linear will require a ramdisk to set up
the mount for system. In this world, first stage init will be a part
of this ramdisk and handle setting up dm-linear, mounting the
necessary partitions, then pivoting to the system image, which will
become the root partition.
This also enables previous devices without system-as-root, to be
unified with system-as-root devices for all aspects of boot after the
pivot_root.
Bug: 79758715
Test: boot hikey
Test: boot sailfish, boot sailfish into recovery
Change-Id: Iefa88a3ec5994e7989aa9f26f2de0351ffa5468b
diff --git a/init/Android.bp b/init/Android.bp
index d42ab8a..84a78e2 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -92,6 +92,7 @@
cc_library_static {
name: "libinit",
+ recovery_available: true,
defaults: ["init_defaults"],
srcs: [
"action.cpp",
@@ -107,7 +108,6 @@
"first_stage_mount.cpp",
"import_parser.cpp",
"init.cpp",
- "init_first_stage.cpp",
"keychords.cpp",
"modalias_handler.cpp",
"parser.cpp",
@@ -138,29 +138,21 @@
},
}
-/*
-This is not yet ready, see the below TODOs for what is missing
-
cc_binary {
- // TODO: Missing,
- //LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
- //LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
-
- name: "init",
+ name: "init_second_stage",
+ recovery_available: true,
+ stem: "init",
defaults: ["init_defaults"],
+ static_libs: ["libinit"],
required: [
"e2fsdroid",
"mke2fs",
"sload_f2fs",
"make_f2fs",
],
- static_executable: true,
srcs: ["main.cpp"],
- symlinks: [
- "sbin/ueventd",
- ],
+ symlinks: ["ueventd"],
}
-*/
// Tests
// ------------------------------------------------------------------------------
diff --git a/init/Android.mk b/init/Android.mk
index 9d9d368..d20509b 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -41,35 +41,35 @@
include $(CLEAR_VARS)
LOCAL_CPPFLAGS := $(init_cflags)
-LOCAL_SRC_FILES := main.cpp
+LOCAL_SRC_FILES := \
+ devices.cpp \
+ first_stage_mount.cpp \
+ init_first_stage.cpp \
+ reboot_utils.cpp \
+ selinux.cpp \
+ uevent_listener.cpp \
+ util.cpp \
-LOCAL_MODULE:= init
+LOCAL_MODULE := init
+
+LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
LOCAL_STATIC_LIBRARIES := \
- libinit \
- libbootloader_message \
libfs_mgr \
libfec \
libfec_rs \
- libhidl-gen-utils \
libsquashfs_utils \
liblogwrap \
libext4_utils \
libseccomp_policy \
libcrypto_utils \
libsparse \
- libprocessgroup \
libavb \
libkeyutils \
- libprotobuf-cpp-lite \
- libpropertyinfoserializer \
- libpropertyinfoparser \
liblp \
-
-shared_libs := \
libcutils \
libbase \
liblog \
@@ -77,27 +77,11 @@
libdl \
libz \
libselinux \
-
-ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-# init is static executable for non-system-as-root devices, because the dynamic linker
-# and shared libs are not available before /system is mounted, but init has to run
-# before the partition is mounted.
-LOCAL_STATIC_LIBRARIES += $(shared_libs) libc++_static
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-else
-LOCAL_SHARED_LIBRARIES := $(shared_libs) libc++
-endif
-shared_libs :=
+ libcap \
LOCAL_REQUIRED_MODULES := \
- e2fsdroid \
- mke2fs \
- sload_f2fs \
- make_f2fs \
-
-# Create symlinks.
-LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
- ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
+ init_second_stage \
+ init_second_stage.recovery \
LOCAL_SANITIZE := signed-integer-overflow
include $(BUILD_EXECUTABLE)
diff --git a/init/init.cpp b/init/init.cpp
index ad80c98..b550f1b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -565,8 +565,6 @@
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
}
-int first_stage_main(int argc, char** argv);
-
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
@@ -578,10 +576,6 @@
return SubcontextMain(argc, argv, &function_map);
}
- if (getenv("INIT_SECOND_STAGE") == nullptr) {
- return first_stage_main(argc, argv);
- }
-
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
@@ -617,7 +611,6 @@
if (avb_version) property_set("ro.boot.avb_version", avb_version);
// Clean up our environment.
- unsetenv("INIT_SECOND_STAGE");
unsetenv("INIT_STARTED_AT");
unsetenv("INIT_SELINUX_TOOK");
unsetenv("INIT_AVB_VERSION");
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index ef9ce81..b367f2a 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -51,7 +51,7 @@
});
}
-int first_stage_main(int argc, char** argv) {
+int main(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
@@ -141,17 +141,15 @@
// Unneeded? It's an ext4 file system so shouldn't it have the right domain already?
// We're in the kernel domain, so re-exec init to transition to the init domain now
// that the SELinux policy has been loaded.
- if (selinux_android_restorecon("/init", 0) == -1) {
- PLOG(FATAL) << "restorecon failed of /init failed";
+ if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
+ PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
}
- setenv("INIT_SECOND_STAGE", "true", 1);
-
static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
- const char* path = argv[0];
+ const char* path = "/system/bin/init";
const char* args[] = {path, nullptr};
execv(path, const_cast<char**>(args));
@@ -164,3 +162,7 @@
} // namespace init
} // namespace android
+
+int main(int argc, char** argv) {
+ return android::init::main(argc, argv);
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 486d096..ca8655f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -732,7 +732,7 @@
## Daemon processes to be run by init.
##
-service ueventd /sbin/ueventd
+service ueventd /system/bin/ueventd
class core
critical
seclabel u:r:ueventd:s0