You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
ksud(feat): Parse KMI from boot or kernel
This commit is contained in:
@@ -97,6 +97,61 @@ pub fn get_current_kmi() -> Result<String> {
|
|||||||
bail!("Unsupported platform")
|
bail!("Unsupported platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_kmi_from_kernel(kernel: &PathBuf, workdir: &Path) -> Result<String> {
|
||||||
|
use regex::Regex;
|
||||||
|
use std::fs::{copy, File};
|
||||||
|
use std::io::{BufReader, Read};
|
||||||
|
let kernel_path = workdir.join("kernel");
|
||||||
|
copy(&kernel, &kernel_path).context("Failed to copy kernel")?;
|
||||||
|
|
||||||
|
let file = File::open(&kernel_path).context("Failed to open kernel file")?;
|
||||||
|
let mut reader = BufReader::new(file);
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
reader
|
||||||
|
.read_to_end(&mut buffer)
|
||||||
|
.context("Failed to read kernel file")?;
|
||||||
|
|
||||||
|
let printable_strings: Vec<&str> = buffer
|
||||||
|
.split(|&b| b == 0)
|
||||||
|
.filter_map(|slice| std::str::from_utf8(slice).ok())
|
||||||
|
.filter(|s| s.chars().all(|c| c.is_ascii_graphic() || c == ' '))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let re =
|
||||||
|
Regex::new(r"(?:.* )?(\d+\.\d+)(?:\S+)?(android\d+)").context("Failed to compile regex")?;
|
||||||
|
for s in printable_strings {
|
||||||
|
if let Some(caps) = re.captures(s) {
|
||||||
|
if let (Some(kernel_version), Some(android_version)) = (caps.get(1), caps.get(2)) {
|
||||||
|
let kmi = format!("{}-{}", android_version.as_str(), kernel_version.as_str());
|
||||||
|
return Ok(kmi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("- Failed to get KMI version");
|
||||||
|
bail!("Try to choose LKM manually")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Result<String> {
|
||||||
|
let image_path = workdir.join("image");
|
||||||
|
|
||||||
|
std::fs::copy(&image, &image_path).context("Failed to copy image")?;
|
||||||
|
|
||||||
|
let status = Command::new(magiskboot)
|
||||||
|
.current_dir(workdir)
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.arg("unpack")
|
||||||
|
.arg(&image_path)
|
||||||
|
.status()
|
||||||
|
.context("Failed to execute magiskboot command")?;
|
||||||
|
|
||||||
|
if !status.success() {
|
||||||
|
bail!("magiskboot unpack failed with status: {:?}", status.code().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_kmi_from_kernel(&image_path, workdir)
|
||||||
|
}
|
||||||
|
|
||||||
fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> {
|
fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> {
|
||||||
let status = Command::new(magiskboot)
|
let status = Command::new(magiskboot)
|
||||||
.current_dir(workdir)
|
.current_dir(workdir)
|
||||||
@@ -313,10 +368,34 @@ fn do_patch(
|
|||||||
let tmpdir = tempdir::TempDir::new("KernelSU").context("create temp dir failed")?;
|
let tmpdir = tempdir::TempDir::new("KernelSU").context("create temp dir failed")?;
|
||||||
let workdir = tmpdir.path();
|
let workdir = tmpdir.path();
|
||||||
|
|
||||||
|
// extract magiskboot
|
||||||
|
let magiskboot = find_magiskboot(magiskboot_path, workdir)?;
|
||||||
|
|
||||||
let kmi = if let Some(kmi) = kmi {
|
let kmi = if let Some(kmi) = kmi {
|
||||||
kmi
|
kmi
|
||||||
} else {
|
} else {
|
||||||
get_current_kmi().context("Unknown KMI, please choose LKM manually")?
|
let kmi = match get_current_kmi() {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(e) => {
|
||||||
|
println!("- {}", e);
|
||||||
|
if let Some(image_path) = &image {
|
||||||
|
println!(
|
||||||
|
"- Trying to auto detect KMI version for {}",
|
||||||
|
image_path.to_str().unwrap()
|
||||||
|
);
|
||||||
|
parse_kmi_from_boot(&magiskboot, image_path, tmpdir.path())?
|
||||||
|
} else if let Some(kernel_path) = &kernel {
|
||||||
|
println!(
|
||||||
|
"- Trying to auto detect KMI version for {}",
|
||||||
|
kernel_path.to_str().unwrap()
|
||||||
|
);
|
||||||
|
parse_kmi_from_kernel(kernel_path, tmpdir.path())?
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
kmi
|
||||||
};
|
};
|
||||||
|
|
||||||
let skip_init = kmi.starts_with("android12-");
|
let skip_init = kmi.starts_with("android12-");
|
||||||
@@ -329,9 +408,6 @@ fn do_patch(
|
|||||||
// try extract magiskboot/bootctl
|
// try extract magiskboot/bootctl
|
||||||
let _ = assets::ensure_binaries(false);
|
let _ = assets::ensure_binaries(false);
|
||||||
|
|
||||||
// extract magiskboot
|
|
||||||
let magiskboot = find_magiskboot(magiskboot_path, workdir)?;
|
|
||||||
|
|
||||||
if let Some(kernel) = kernel {
|
if let Some(kernel) = kernel {
|
||||||
std::fs::copy(kernel, workdir.join("kernel")).context("copy kernel from failed")?;
|
std::fs::copy(kernel, workdir.join("kernel")).context("copy kernel from failed")?;
|
||||||
}
|
}
|
||||||
@@ -558,7 +634,7 @@ fn find_boot_image(
|
|||||||
} else {
|
} else {
|
||||||
if cfg!(not(target_os = "android")) {
|
if cfg!(not(target_os = "android")) {
|
||||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||||
bail!("please specify a boot image");
|
bail!("Please specify a boot image");
|
||||||
}
|
}
|
||||||
let mut slot_suffix =
|
let mut slot_suffix =
|
||||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||||
|
|||||||
Reference in New Issue
Block a user