Move BootConfig to rust

This commit is contained in:
LoveSy 2025-01-30 18:39:34 +08:00 committed by John Wu
parent 540253a55b
commit 6c612d66d7
6 changed files with 48 additions and 44 deletions

View File

@ -7,4 +7,5 @@
#include "../base-rs.hpp"
using rust::xpipe2;
using rust::fd_path;
using rust::fd_path;
using kv_pairs = std::vector<std::pair<std::string, std::string>>;

View File

@ -118,7 +118,7 @@ static bool check_key_combo() {
return false;
}
void BootConfig::set(const kv_pairs &kv) {
void BootConfig::set(const kv_pairs &kv) noexcept {
for (const auto &[key, value] : kv) {
if (key == "androidboot.slot_suffix") {
// Many Amlogic devices are A-only but have slot_suffix...
@ -126,10 +126,10 @@ void BootConfig::set(const kv_pairs &kv) {
LOGW("Skip invalid androidboot.slot_suffix=[normal]\n");
continue;
}
strscpy(slot, value.data(), sizeof(slot));
strscpy(slot.data(), value.data(), slot.size());
} else if (key == "androidboot.slot") {
slot[0] = '_';
strscpy(slot + 1, value.data(), sizeof(slot) - 1);
strscpy(slot.data() + 1, value.data(), slot.size() - 1);
} else if (key == "skip_initramfs") {
skip_initramfs = true;
} else if (key == "androidboot.force_normal_boot") {
@ -137,13 +137,13 @@ void BootConfig::set(const kv_pairs &kv) {
} else if (key == "rootwait") {
rootwait = true;
} else if (key == "androidboot.android_dt_dir") {
strscpy(dt_dir, value.data(), sizeof(dt_dir));
strscpy(dt_dir.data(), value.data(), dt_dir.size());
} else if (key == "androidboot.hardware") {
strscpy(hardware, value.data(), sizeof(hardware));
strscpy(hardware.data(), value.data(), hardware.size());
} else if (key == "androidboot.hardware.platform") {
strscpy(hardware_plat, value.data(), sizeof(hardware_plat));
strscpy(hardware_plat.data(), value.data(), hardware_plat.size());
} else if (key == "androidboot.fstab_suffix") {
strscpy(fstab_suffix, value.data(), sizeof(fstab_suffix));
strscpy(fstab_suffix.data(), value.data(), fstab_suffix.size());
} else if (key == "qemu") {
emulator = true;
} else if (key == "androidboot.partition_map") {
@ -151,34 +151,36 @@ void BootConfig::set(const kv_pairs &kv) {
// For example, "androidboot.partition_map=vdb,metadata;vdc,userdata" maps
// "vdb" to "metadata", and "vdc" to "userdata".
// https://android.googlesource.com/platform/system/core/+/refs/heads/android13-release/init/devices.cpp#191
partition_map = parse_partition_map(value);
for (const auto &[k, v]: parse_partition_map(value)) {
partition_map.emplace_back(k, v);
}
}
}
}
void BootConfig::print() {
void BootConfig::print() const noexcept {
LOGD("skip_initramfs=[%d]\n", skip_initramfs);
LOGD("force_normal_boot=[%d]\n", force_normal_boot);
LOGD("rootwait=[%d]\n", rootwait);
LOGD("slot=[%s]\n", slot);
LOGD("dt_dir=[%s]\n", dt_dir);
LOGD("fstab_suffix=[%s]\n", fstab_suffix);
LOGD("hardware=[%s]\n", hardware);
LOGD("hardware.platform=[%s]\n", hardware_plat);
LOGD("slot=[%s]\n", slot.data());
LOGD("dt_dir=[%s]\n", dt_dir.data());
LOGD("fstab_suffix=[%s]\n", fstab_suffix.data());
LOGD("hardware=[%s]\n", hardware.data());
LOGD("hardware.platform=[%s]\n", hardware_plat.data());
LOGD("emulator=[%d]\n", emulator);
}
#define read_dt(name, key) \
ssprintf(file_name, sizeof(file_name), "%s/" name, dt_dir); \
ssprintf(file_name, sizeof(file_name), "%s/" name, dt_dir.data()); \
if (access(file_name, R_OK) == 0) { \
string data = full_read(file_name); \
if (!data.empty()) { \
data.pop_back(); \
strscpy(key, data.data(), sizeof(key)); \
strscpy(key.data(), data.data(), key.size()); \
} \
}
void BootConfig::init() {
void BootConfig::init() noexcept {
set(parse_cmdline(full_read("/proc/cmdline")));
set(parse_bootconfig(full_read("/proc/bootconfig")));
@ -191,7 +193,7 @@ void BootConfig::init() {
});
if (dt_dir[0] == '\0')
strscpy(dt_dir, DEFAULT_DT_DIR, sizeof(dt_dir));
strscpy(dt_dir.data(), DEFAULT_DT_DIR, dt_dir.size());
char file_name[128];
read_dt("fstab_suffix", fstab_suffix)

View File

@ -3,26 +3,6 @@
#include "init-rs.hpp"
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
struct BootConfig {
bool skip_initramfs;
bool force_normal_boot;
bool rootwait;
bool emulator;
char slot[3];
char dt_dir[64];
char fstab_suffix[32];
char hardware[32];
char hardware_plat[32];
kv_pairs partition_map;
void init();
private:
void set(const kv_pairs &);
void print();
};
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
#define INIT_PATH "/system/bin/init"
#define REDIR_PATH "/data/magiskinit"

View File

@ -14,6 +14,23 @@ mod rootdir;
#[cxx::bridge]
pub mod ffi {
struct KeyValue {
key: String,
value: String,
}
struct BootConfig {
skip_initramfs: bool,
force_normal_boot: bool,
rootwait: bool,
emulator: bool,
slot: [c_char; 3],
dt_dir: [c_char; 64],
fstab_suffix: [c_char; 32],
hardware: [c_char; 32],
hardware_plat: [c_char; 32],
partition_map: Vec<KeyValue>,
}
#[namespace = "rust"]
extern "Rust" {
fn setup_klog();
@ -30,5 +47,9 @@ pub mod ffi {
#[namespace = "rust"]
#[cxx_name = "Utf8CStr"]
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
fn init(self: &mut BootConfig);
fn print(self: &BootConfig);
type kv_pairs;
fn set(self: &mut BootConfig, config: &kv_pairs);
}
}

View File

@ -60,10 +60,10 @@ void MagiskInit::collect_devices() {
strscpy(dev.dmname, name.data(), sizeof(dev.dmname));
}
if (auto it = std::ranges::find_if(config.partition_map, [&](const auto &i) {
return i.first == dev.devname;
return i.key == dev.devname;
}); dev.partname[0] == '\0' && it != config.partition_map.end()) {
// use androidboot.partition_map as partname fallback.
strscpy(dev.partname, it->second.data(), sizeof(dev.partname));
strscpy(dev.partname, it->value.data(), sizeof(dev.partname));
}
sprintf(path, "/sys/dev/block/%s", entry->d_name);
xrealpath(path, dev.devpath, sizeof(dev.devpath));
@ -163,7 +163,7 @@ bool MagiskInit::mount_system_root() {
// Try normal partname
char sys_part[32];
sprintf(sys_part, "system%s", config.slot);
sprintf(sys_part, "system%s", config.slot.data());
dev = find_block(sys_part);
if (dev > 0)
goto mount_root;

View File

@ -64,7 +64,7 @@ bool MagiskInit::hijack_sepolicy() {
// This only happens on Android 8.0 - 9.0
char buf[4096];
ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir);
ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir.data());
dt_compat = full_read(buf);
if (dt_compat.empty()) {
// Device does not do early mount and uses monolithic policy
@ -106,7 +106,7 @@ bool MagiskInit::hijack_sepolicy() {
int fd = xopen(MOCK_COMPAT, O_WRONLY);
char buf[4096];
ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir);
ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir.data());
xumount2(buf, MNT_DETACH);
hijack();