Andrew Gunnerson 1f8c063dc6 Fix booting into recovery with Android 13 GKI kernels
With Android 13 GKI kernels, the boot partition has no ramdisk, so
Magisk constructs one from scratch. In this scenario, there's no backup
init binary at /.backup/init. For normal boot, magiskinit will symlink
/init -> /system/bin/init if needed. This commit implements the same
for booting into recovery. Before, magiskinit would just exec itself
over and over again because it couldn't restore the backup init.

Signed-off-by: Andrew Gunnerson <chillermillerlong@hotmail.com>
2022-07-18 13:33:50 -07:00
..
2022-07-06 01:16:08 -07:00
2022-05-09 20:53:47 -07:00
2019-03-03 06:35:25 -05:00

Native Development

Prerequisite

Install the NDK required to build and develop Magisk with ./build.py ndk. The NDK will be installed to $ANDROID_SDK_ROOT/ndk/magisk. You don't need to manually install a Rust toolchain with rustup, as the NDK installed already has a Rust toolchain bundled.

Code Paths

  • jni: Magisk's code in C++
  • jni/external: external dependencies, mostly submodules
  • rust: Magisk's code in Rust
  • src: irrelevant, only exists to setup a native Android Studio project

Build Configs

All C/C++ code and its dependencies are built with ndk-build and configured with several *.mk files scatterred in many places.

The rust folder is a proper Cargo workspace, and all Rust code is built with cargo just like any other Rust projects.

Rust + C/C++

To reduce complexity involved in linking, all Rust code is built as staticlib and linked to C++ targets to ensure our final product is built with an officially supported NDK build system. Each C++ target can at most link to one Rust staticlib or else multiple definitions error will occur.

We use the cxx project for interop between Rust and C++. Although cxx supports interop in both directions, for Magisk, it is strongly advised to avoid calling C++ functions in Rust; if some functionality required in Rust is already implemented in C++, the desired solution is to port the C++ implementation into Rust and export the migrated function back to C++.

Development / IDE

All C++ code should be recognized and properly indexed by Android Studio out of the box. For Rust:

  • Install the Rust plugin in Android Studio
  • In Preferences > Languages & Frameworks > Rust, set $ANDROID_SDK_ROOT/ndk/magisk/toolchains/rust/bin as the toolchain location
  • Open native/rust/Cargo.toml, and select "Attach" in the "No Cargo projects found" banner

Note: run ./build.py binary before developing to make sure generated code is created.