embed LKM to ksud (#1472)

This commit is contained in:
weishu
2024-03-18 23:12:46 +08:00
committed by GitHub
parent 4bad691ec8
commit 9759a779cd
6 changed files with 105 additions and 57 deletions

View File

@@ -13,7 +13,11 @@ on:
- '.github/workflows/ksud.yml'
- 'userspace/ksud/**'
jobs:
build-lkm:
uses: ./.github/workflows/build-lkm.yml
secrets: inherit
build:
needs: build-lkm
strategy:
matrix:
include:

View File

@@ -20,6 +20,14 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Prepare LKM fies
run: |
cp android*-lkm/*_kernelsu.ko ./userspace/ksud/bin/aarch64/
# cross build failed after Rust 1.68, see https://github.com/cross-rs/cross/issues/1222
- name: Setup rustup
run: |

1
userspace/ksud/bin/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
**/*.ko

View File

@@ -22,7 +22,8 @@ struct Asset;
pub fn ensure_binaries(ignore_if_exist: bool) -> Result<()> {
for file in Asset::iter() {
if file == "ksuinit" {
if file == "ksuinit" || file.ends_with(".ko") {
// don't extract ksuinit and kernel modules
continue;
}
let asset = Asset::get(&file).ok_or(anyhow::anyhow!("asset not found: {}", file))?;

View File

@@ -47,6 +47,25 @@ pub fn get_kernel_version() -> Result<(i32, i32, i32)> {
}
}
#[cfg(target_os = "android")]
fn parse_kmi() -> Result<String> {
use regex::Regex;
let uname = rustix::system::uname();
let version = uname.release().to_string_lossy();
let re = Regex::new(r"(.* )?(\d+\.\d+)(\S+)?(android\d+)(.*)")?;
let cap = re
.captures(&version)
.ok_or_else(|| anyhow::anyhow!("No match found"))?;
let android_version = cap.get(4).map_or("", |m| m.as_str());
let kernel_version = cap.get(2).map_or("", |m| m.as_str());
Ok(format!("{android_version}-{kernel_version}"))
}
#[cfg(not(target_os = "android"))]
fn parse_kmi() -> Result<String> {
bail!("Unknown KMI, try use --kmi to specify it.")
}
fn do_cpio_cmd(magiskboot: &Path, workding_dir: &Path, cmd: &str) -> Result<()> {
let status = Command::new(magiskboot)
.current_dir(workding_dir)
@@ -98,9 +117,10 @@ pub fn patch(
ota: bool,
flash: bool,
out: Option<PathBuf>,
magiskboot_path: Option<PathBuf>,
magiskboot: Option<PathBuf>,
kmi: Option<String>,
) -> Result<()> {
let result = do_patch(image, kernel, kmod, init, ota, flash, out, magiskboot_path);
let result = do_patch(image, kernel, kmod, init, ota, flash, out, magiskboot, kmi);
if let Err(ref e) = result {
println!("- Install Error: {e}");
}
@@ -117,6 +137,7 @@ fn do_patch(
flash: bool,
out: Option<PathBuf>,
magiskboot_path: Option<PathBuf>,
kmi: Option<String>,
) -> Result<()> {
println!(include_str!("banner"));
@@ -132,8 +153,6 @@ fn do_patch(
init.is_none() && kmod.is_none(),
"init and module must not be specified."
);
} else {
ensure!(kmod.is_some(), "module must be specified");
}
let workding_dir =
@@ -207,18 +226,29 @@ fn do_patch(
.with_context(|| "copy kernel from failed".to_string())?;
}
if let Some(kmod) = kmod {
println!("- Preparing assets");
std::fs::copy(kmod, workding_dir.path().join("kernelsu.ko"))
.with_context(|| "copy kernel module failed".to_string())?;
let kmod_file = workding_dir.path().join("kernelsu.ko");
if let Some(kmod) = kmod {
std::fs::copy(kmod, kmod_file).with_context(|| "copy kernel module failed".to_string())?;
} else {
// If kmod is not specified, extract from assets
let kmi = if let Some(kmi) = kmi {
kmi
} else {
parse_kmi()?
};
println!("- KMI: {kmi}");
let name = format!("{kmi}_kernelsu.ko");
assets::copy_assets_to_file(&name, kmod_file)
.with_context(|| format!("Failed to copy {name}"))?;
};
let init_file = workding_dir.path().join("init");
if let Some(init) = init {
std::fs::copy(init, workding_dir.path().join("init"))
.with_context(|| "copy init failed".to_string())?;
std::fs::copy(init, init_file).with_context(|| "copy init failed".to_string())?;
} else {
crate::assets::copy_assets_to_file("ksuinit", init_file)
.with_context(|| "copy ksuinit failed")?;
assets::copy_assets_to_file("ksuinit", init_file).with_context(|| "copy ksuinit failed")?;
}
// magiskboot unpack boot.img
@@ -260,7 +290,6 @@ fn do_patch(
workding_dir.path(),
"add 0755 kernelsu.ko kernelsu.ko",
)?;
}
println!("- Repacking boot image");
// magiskboot repack boot.img

View File

@@ -59,7 +59,7 @@ enum Commands {
#[arg(short, long)]
kernel: Option<PathBuf>,
/// LKM module path to replace
/// LKM module path to replace, if not specified, will use the builtin one
#[arg(short, long)]
module: Option<PathBuf>,
@@ -82,6 +82,10 @@ enum Commands {
/// magiskboot path, if not specified, will use builtin one
#[arg(long, default_value = None)]
magiskboot: Option<PathBuf>,
/// KMI version, if specified, will use the specified KMI
#[arg(long, default_value = None)]
kmi: Option<String>,
},
/// For developers
Debug {
@@ -316,7 +320,8 @@ pub fn run() -> Result<()> {
flash,
out,
magiskboot,
} => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot),
kmi,
} => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot, kmi),
};
if let Err(e) = &result {