ksud: implement patching LKM vendor_ramdisk/ramdisk.cpio for compatibily needed for some pixel devices

This commit is contained in:
Rifat Azad
2025-06-26 10:33:58 +06:00
parent 39717b0a3f
commit b74e953ad2
2 changed files with 218 additions and 38 deletions

View File

@@ -182,6 +182,21 @@ fn do_vendor_init_boot_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) ->
Ok(()) Ok(())
} }
fn do_vendor_ramdisk_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("cpio")
.arg(vendor_ramdisk_cpio)
.arg(cmd)
.status()?;
ensure!(status.success(), "magiskboot cpio {} failed", cmd);
Ok(())
}
fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> { fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot) let status = Command::new(magiskboot)
.current_dir(workdir) .current_dir(workdir)
@@ -207,6 +222,19 @@ fn is_magisk_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Resu
Ok(status.code() == Some(1)) Ok(status.code() == Some(1))
} }
fn is_magisk_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.args(["cpio", vendor_ramdisk_cpio.to_str().unwrap(), "test"])
.status()?;
// 0: stock, 1: magisk
Ok(status.code() == Some(1))
}
fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> { fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot) let status = Command::new(magiskboot)
.current_dir(workdir) .current_dir(workdir)
@@ -234,6 +262,22 @@ fn is_kernelsu_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Re
Ok(status.success()) Ok(status.success())
} }
fn is_kernelsu_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.args([
"cpio",
vendor_ramdisk_cpio.to_str().unwrap(),
"exists kernelsu.ko",
])
.status()?;
Ok(status.success())
}
fn dd<P: AsRef<Path>, Q: AsRef<Path>>(ifile: P, ofile: Q) -> Result<()> { fn dd<P: AsRef<Path>, Q: AsRef<Path>>(ifile: P, ofile: Q) -> Result<()> {
let status = Command::new("dd") let status = Command::new("dd")
.stdout(Stdio::null()) .stdout(Stdio::null())
@@ -279,11 +323,21 @@ pub fn restore(
ensure!(status.success(), "magiskboot unpack failed"); ensure!(status.success(), "magiskboot unpack failed");
let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
let no_vendor_init_boot = !workdir
.join("vendor_ramdisk")
.join("init_boot.cpio")
.exists();
let no_vendor_ramdisk = !workdir
.join("vendor_ramdisk")
.join("ramdisk.cpio")
.exists();
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_init_boot = let is_kernelsu_patched_vendor_init_boot =
is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_ramdisk =
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
ensure!( ensure!(
is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot, is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot || is_kernelsu_patched_vendor_ramdisk,
"boot image is not patched by KernelSU Next" "boot image is not patched by KernelSU Next"
); );
@@ -318,16 +372,30 @@ pub fn restore(
if new_boot.is_none() { if new_boot.is_none() {
if no_ramdisk { if no_ramdisk {
// vendor init_boot restore if !no_vendor_init_boot {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; // vendor init_boot restore
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
let status = let status =
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status { if status {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else { } else {
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
std::fs::remove_file(vendor_init_boot)?; std::fs::remove_file(vendor_init_boot)?;
}
} else if !no_vendor_ramdisk {
// vendor ramdisk restore
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
let status =
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else {
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
std::fs::remove_file(vendor_ramdisk)?;
}
} }
} else { } else {
// remove kernelsu.ko // remove kernelsu.ko
@@ -517,14 +585,20 @@ fn do_patch(
.join("vendor_ramdisk") .join("vendor_ramdisk")
.join("init_boot.cpio") .join("init_boot.cpio")
.exists(); .exists();
if no_ramdisk && no_vendor_init_boot { let no_vendor_ramdisk = !workdir
.join("vendor_ramdisk")
.join("ramdisk.cpio")
.exists();
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
bail!("No compatible ramdisk found."); bail!("No compatible ramdisk found.");
} }
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?; let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
let is_magisk_patched_vendor_init_boot = let is_magisk_patched_vendor_init_boot =
is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?; is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_magisk_patched_vendor_ramdisk =
is_magisk_patched_vendor_ramdisk(&magiskboot, workdir)?;
ensure!( ensure!(
!is_magisk_patched || !is_magisk_patched_vendor_init_boot, !is_magisk_patched || !is_magisk_patched_vendor_init_boot || !is_magisk_patched_vendor_ramdisk,
"Cannot work with Magisk patched image" "Cannot work with Magisk patched image"
); );
@@ -532,14 +606,25 @@ fn do_patch(
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_init_boot = let is_kernelsu_patched_vendor_init_boot =
is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_ramdisk =
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
let mut need_backup = false; let mut need_backup = false;
if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) { if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
{
if no_ramdisk { if no_ramdisk {
// vendor init_boot patching if !no_vendor_init_boot {
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); // vendor init_boot patching
if status.is_ok() { let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; if status.is_ok() {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
}
} else if !no_vendor_ramdisk {
// vendor ramdisk patching
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
if status.is_ok() {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
}
} }
} else { } else {
// kernelsu.ko is not exist, backup init if necessary // kernelsu.ko is not exist, backup init if necessary
@@ -552,8 +637,13 @@ fn do_patch(
} }
if no_ramdisk { if no_ramdisk {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; if !no_vendor_init_boot {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} else if !no_vendor_ramdisk {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
}
} else { } else {
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;

View File

@@ -182,6 +182,21 @@ fn do_vendor_init_boot_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) ->
Ok(()) Ok(())
} }
fn do_vendor_ramdisk_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("cpio")
.arg(vendor_ramdisk_cpio)
.arg(cmd)
.status()?;
ensure!(status.success(), "magiskboot cpio {} failed", cmd);
Ok(())
}
fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> { fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot) let status = Command::new(magiskboot)
.current_dir(workdir) .current_dir(workdir)
@@ -207,6 +222,19 @@ fn is_magisk_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Resu
Ok(status.code() == Some(1)) Ok(status.code() == Some(1))
} }
fn is_magisk_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.args(["cpio", vendor_ramdisk_cpio.to_str().unwrap(), "test"])
.status()?;
// 0: stock, 1: magisk
Ok(status.code() == Some(1))
}
fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> { fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot) let status = Command::new(magiskboot)
.current_dir(workdir) .current_dir(workdir)
@@ -234,6 +262,22 @@ fn is_kernelsu_patched_vendor_init_boot(magiskboot: &Path, workdir: &Path) -> Re
Ok(status.success()) Ok(status.success())
} }
fn is_kernelsu_patched_vendor_ramdisk(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let vendor_ramdisk_cpio = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.args([
"cpio",
vendor_ramdisk_cpio.to_str().unwrap(),
"exists kernelsu.ko",
])
.status()?;
Ok(status.success())
}
fn dd<P: AsRef<Path>, Q: AsRef<Path>>(ifile: P, ofile: Q) -> Result<()> { fn dd<P: AsRef<Path>, Q: AsRef<Path>>(ifile: P, ofile: Q) -> Result<()> {
let status = Command::new("dd") let status = Command::new("dd")
.stdout(Stdio::null()) .stdout(Stdio::null())
@@ -279,11 +323,21 @@ pub fn restore(
ensure!(status.success(), "magiskboot unpack failed"); ensure!(status.success(), "magiskboot unpack failed");
let no_ramdisk = !workdir.join("ramdisk.cpio").exists(); let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
let no_vendor_init_boot = !workdir
.join("vendor_ramdisk")
.join("init_boot.cpio")
.exists();
let no_vendor_ramdisk = !workdir
.join("vendor_ramdisk")
.join("ramdisk.cpio")
.exists();
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_init_boot = let is_kernelsu_patched_vendor_init_boot =
is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_ramdisk =
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
ensure!( ensure!(
is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot, is_kernelsu_patched || is_kernelsu_patched_vendor_init_boot || is_kernelsu_patched_vendor_ramdisk,
"boot image is not patched by KernelSU Next" "boot image is not patched by KernelSU Next"
); );
@@ -318,16 +372,30 @@ pub fn restore(
if new_boot.is_none() { if new_boot.is_none() {
if no_ramdisk { if no_ramdisk {
// vendor init_boot restore if !no_vendor_init_boot {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?; // vendor init_boot restore
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
let status = let status =
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok(); do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status { if status {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?; do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else { } else {
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio"); let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
std::fs::remove_file(vendor_init_boot)?; std::fs::remove_file(vendor_init_boot)?;
}
} else if !no_vendor_ramdisk {
// vendor ramdisk restore
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
let status =
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else {
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
std::fs::remove_file(vendor_ramdisk)?;
}
} }
} else { } else {
// remove kernelsu.ko // remove kernelsu.ko
@@ -517,14 +585,20 @@ fn do_patch(
.join("vendor_ramdisk") .join("vendor_ramdisk")
.join("init_boot.cpio") .join("init_boot.cpio")
.exists(); .exists();
if no_ramdisk && no_vendor_init_boot { let no_vendor_ramdisk = !workdir
.join("vendor_ramdisk")
.join("ramdisk.cpio")
.exists();
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
bail!("No compatible ramdisk found."); bail!("No compatible ramdisk found.");
} }
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?; let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
let is_magisk_patched_vendor_init_boot = let is_magisk_patched_vendor_init_boot =
is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?; is_magisk_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_magisk_patched_vendor_ramdisk =
is_magisk_patched_vendor_ramdisk(&magiskboot, workdir)?;
ensure!( ensure!(
!is_magisk_patched || !is_magisk_patched_vendor_init_boot, !is_magisk_patched || !is_magisk_patched_vendor_init_boot || !is_magisk_patched_vendor_ramdisk,
"Cannot work with Magisk patched image" "Cannot work with Magisk patched image"
); );
@@ -532,14 +606,25 @@ fn do_patch(
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?; let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_init_boot = let is_kernelsu_patched_vendor_init_boot =
is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?; is_kernelsu_patched_vendor_init_boot(&magiskboot, workdir)?;
let is_kernelsu_patched_vendor_ramdisk =
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
let mut need_backup = false; let mut need_backup = false;
if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) { if !is_kernelsu_patched || (no_ramdisk && !is_kernelsu_patched_vendor_init_boot) || (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
{
if no_ramdisk { if no_ramdisk {
// vendor init_boot patching if !no_vendor_init_boot {
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init"); // vendor init_boot patching
if status.is_ok() { let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?; if status.is_ok() {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
}
} else if !no_vendor_ramdisk {
// vendor ramdisk patching
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
if status.is_ok() {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
}
} }
} else { } else {
// kernelsu.ko is not exist, backup init if necessary // kernelsu.ko is not exist, backup init if necessary
@@ -552,8 +637,13 @@ fn do_patch(
} }
if no_ramdisk { if no_ramdisk {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; if !no_vendor_init_boot {
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
} else if !no_vendor_ramdisk {
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
}
} else { } else {
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?; do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;