website: Kill website
* It has been separated into SukiSU-Ultra/Website Signed-off-by: WenHao2130 <wenhao2130@outlook.com>
This commit is contained in:
150
website/.gitignore
vendored
150
website/.gitignore
vendored
@@ -1,150 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# from: https://github.com/vuejs/vitepress/blob/main/.gitignore
|
||||
/coverage
|
||||
/src/client/shared.ts
|
||||
/src/node/shared.ts
|
||||
*.log
|
||||
*.tgz
|
||||
.DS_Store
|
||||
.idea
|
||||
.temp
|
||||
.vite_opt_cache
|
||||
.vscode
|
||||
dist
|
||||
cache
|
||||
examples-temp
|
||||
node_modules
|
||||
pnpm-global
|
||||
TODOs.md
|
||||
|
||||
cache
|
||||
@@ -1,32 +0,0 @@
|
||||
import { defineConfig, SiteConfig } from 'vitepress'
|
||||
import locales from './locales'
|
||||
import { readdir, writeFile } from 'fs/promises'
|
||||
import { resolve } from 'path'
|
||||
|
||||
export default defineConfig( {
|
||||
base: '/SukiSU-Ultra/',
|
||||
title: 'KernelSU',
|
||||
locales: locales.locales,
|
||||
head: [
|
||||
['script', {
|
||||
async: 'async',
|
||||
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2610070972052494',
|
||||
crossorigin: 'anonymous',
|
||||
}],
|
||||
],
|
||||
sitemap: {
|
||||
hostname: 'https://kernelsu.org'
|
||||
},
|
||||
buildEnd: async (config: SiteConfig) => {
|
||||
const templateDir = resolve(config.outDir, 'templates');
|
||||
const templateList = resolve(templateDir, "index.json");
|
||||
let files = [];
|
||||
try {
|
||||
files = await readdir(templateDir);
|
||||
files = files.filter(file => !file.startsWith('.'));
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
await writeFile(templateList, JSON.stringify(files));
|
||||
}
|
||||
})
|
||||
@@ -1,62 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'en-US',
|
||||
description: 'A kernel-based root solution for Android GKI devices.',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: 'Last updated',
|
||||
|
||||
sidebar: {
|
||||
'/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'Released under the GPL3 License.',
|
||||
copyright: 'Copyright © 2022-present KernelSU developers.'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'Edit this page on GitHub'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'Guide', link: '/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: 'What is KernelSU?', link: '/guide/what-is-kernelsu' },
|
||||
{ text: 'Difference with Magisk', link: '/guide/difference-with-magisk' },
|
||||
{ text: 'Installation', link: '/guide/installation' },
|
||||
{ text: 'How to build', link: '/guide/how-to-build' },
|
||||
{ text: 'Intergrate for non-GKI devices', link: '/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: 'Unofficially supported devices', link: '/guide/unofficially-support-devices.md' },
|
||||
{ text: 'Module guide', link: '/guide/module.md' },
|
||||
{ text: 'Module WebUI', link: '/guide/module-webui.md' },
|
||||
{ text: 'App Profile', link: '/guide/app-profile.md' },
|
||||
{ text: 'Rescue from bootloop', link: '/guide/rescue-from-bootloop.md' },
|
||||
{ text: 'FAQ', link: '/guide/faq' },
|
||||
{ text: 'Hidden features', link: '/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'id-ID',
|
||||
description: 'Solusi root kernel-based untuk perangkat Android GKI.',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: 'Update Terakhir',
|
||||
|
||||
sidebar: {
|
||||
'/id_ID/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'Rilis Dibawah Lisensi GPL3.',
|
||||
copyright: 'Copyright © 2022-Sekarang pengembang KernelSU.'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'Edit Halaman ini di GitHub'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'Petunjuk', link: '/id_ID/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Petunjuk',
|
||||
items: [
|
||||
{ text: 'Apa itu KernelSU?', link: '/id_ID/guide/what-is-kernelsu' },
|
||||
{ text: 'Instalasi', link: '/id_ID/guide/installation' },
|
||||
{ text: 'Bagaimana cara buildnya?', link: '/id_ID/guide/how-to-build' },
|
||||
{ text: 'Integrasi untuk perangkat non-GKI', link: '/id_ID/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: 'Perangkat yang didukung secara tidak resmi', link: '/id_ID/guide/unofficially-support-devices.md' },
|
||||
{ text: 'Petunjuk module', link: '/id_ID/guide/module.md' },
|
||||
{ text: 'Antisipasi dari bootloop', link: '/id_ID/guide/rescue-from-bootloop.md' },
|
||||
{ text: 'FAQ', link: '/id_ID/guide/faq' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { defineConfig } from 'vitepress'
|
||||
import en from './en'
|
||||
import zh_CN from './zh_CN'
|
||||
import zh_TW from './zh_TW'
|
||||
import vi_VN from './vi_VN'
|
||||
import id_ID from './id_ID'
|
||||
import ja_JP from './ja_JP'
|
||||
import ru_RU from './ru_RU'
|
||||
import pt_BR from './pt_BR'
|
||||
|
||||
export default defineConfig({
|
||||
locales: {
|
||||
root: {
|
||||
label: 'English',
|
||||
lang: en.lang,
|
||||
themeConfig: en.themeConfig,
|
||||
description: en.description
|
||||
},
|
||||
zh_CN: {
|
||||
label: '简体中文',
|
||||
lang: zh_CN.lang,
|
||||
themeConfig: zh_CN.themeConfig,
|
||||
description: zh_CN.description
|
||||
},
|
||||
zh_TW: {
|
||||
label: '繁體中文',
|
||||
lang: zh_TW.lang,
|
||||
themeConfig: zh_TW.themeConfig,
|
||||
description: zh_TW.description
|
||||
},
|
||||
ja_JP: {
|
||||
label: '日本語',
|
||||
lang: ja_JP.lang,
|
||||
themeConfig: ja_JP.themeConfig,
|
||||
description: ja_JP.description
|
||||
},
|
||||
vi_VN: {
|
||||
label: 'Tiếng Việt',
|
||||
lang: vi_VN.lang,
|
||||
themeConfig: vi_VN.themeConfig,
|
||||
description: vi_VN.description
|
||||
},
|
||||
id_ID: {
|
||||
label: 'Bahasa',
|
||||
lang: id_ID.lang,
|
||||
themeConfig: id_ID.themeConfig,
|
||||
description: id_ID.description
|
||||
},
|
||||
ru_RU: {
|
||||
label: 'Русский',
|
||||
lang: ru_RU.lang,
|
||||
themeConfig: ru_RU.themeConfig,
|
||||
description: ru_RU.description
|
||||
},
|
||||
pt_BR: {
|
||||
label: 'Português (Brasil)',
|
||||
lang: pt_BR.lang,
|
||||
themeConfig: pt_BR.themeConfig,
|
||||
description: pt_BR.description
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,59 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'ja-JP',
|
||||
description: 'Android GKI デバイス向けのカーネルベースの root ソリューション',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: '最終更新',
|
||||
|
||||
sidebar: {
|
||||
'/ja_JP/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'GPL3 ライセンスでリリースされています。',
|
||||
copyright: 'Copyright © 2022-現在 KernelSU 開発者。'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'GitHub でこのページを編集'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'ガイド', link: '/ja_JP/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'ガイド',
|
||||
items: [
|
||||
{ text: 'KernelSU とは?', link: '/ja_JP/guide/what-is-kernelsu' },
|
||||
{ text: 'インストール', link: '/ja_JP/guide/installation' },
|
||||
{ text: 'ビルドするには?', link: '/ja_JP/guide/how-to-build' },
|
||||
{ text: '非 GKI デバイスでの実装', link: '/ja_JP/guide/how-to-integrate-for-non-gki' },
|
||||
{ text: '非公式の対応デバイス', link: '/ja_JP/guide/unofficially-support-devices.md' },
|
||||
{ text: 'モジュールのガイド', link: '/ja_JP/guide/module.md' },
|
||||
{ text: 'ブートループからの復旧', link: '/ja_JP/guide/rescue-from-bootloop.md' },
|
||||
{ text: 'よくある質問', link: '/ja_JP/guide/faq' },
|
||||
{ text: '隠し機能', link: '/ja_JP/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'pt-BR',
|
||||
description: 'Uma solução root baseada em kernel para dispositivos Android GKI.',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: 'Última atualização',
|
||||
|
||||
sidebar: {
|
||||
'/pt_BR/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'Lançado sob a Licença GPL3',
|
||||
copyright: 'Copyright © 2022-presente Desenvolvedores do KernelSU.'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'Edite esta página no GitHub'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'Guia', link: '/pt_BR/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Guia',
|
||||
items: [
|
||||
{ text: 'O que é KernelSU?', link: '/pt_BR/guide/what-is-kernelsu' },
|
||||
{ text: 'Diferenças com Magisk', link: '/pt_BR/guide/difference-with-magisk' },
|
||||
{ text: 'Instalação', link: '/pt_BR/guide/installation' },
|
||||
{ text: 'Como compilar', link: '/pt_BR/guide/how-to-build' },
|
||||
{ text: 'Integração para dispositivos não-GKI', link: '/pt_BR/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: 'Dispositivos com suporte não oficial', link: '/pt_BR/guide/unofficially-support-devices.md' },
|
||||
{ text: 'Guias de módulo', link: '/pt_BR/guide/module.md' },
|
||||
{ text: 'Módulo WebUI', link: '/pt_BR/guide/module-webui.md' },
|
||||
{ text: 'Perfil do Aplicativo', link: '/pt_BR/guide/app-profile.md' },
|
||||
{ text: 'Resgate do bootloop', link: '/pt_BR/guide/rescue-from-bootloop.md' },
|
||||
{ text: 'Perguntas frequentes', link: '/pt_BR/guide/faq' },
|
||||
{ text: 'Recursos ocultos', link: '/pt_BR/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'ru-RU',
|
||||
description: 'Решение на основе ядра root для устройств Android GKI.',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: 'последнее обновление',
|
||||
|
||||
sidebar: {
|
||||
'/ru_RU/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'Выпускается под лицензией GPL3.',
|
||||
copyright: 'Авторские права © 2022-текущее Разработчики KernelSU.'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'Редактировать эту страницу на GitHub'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'Руководство', link: '/ru_RU/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Руководство',
|
||||
items: [
|
||||
{ text: 'Что такое KernelSU?', link: '/ru_RU/guide/what-is-kernelsu' },
|
||||
{ text: 'Установка', link: '/ru_RU/guide/installation' },
|
||||
{ text: 'Как собрать?', link: '/ru_RU/guide/how-to-build' },
|
||||
{ text: 'Реализация в устройствах, не относящихся к GKI', link: '/ru_RU/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: 'Неофициально поддерживаемые устройства', link: '/ru_RU/guide/unofficially-support-devices.md' },
|
||||
{ text: 'Руководство по разработке модулей', link: '/ru_RU/guide/module.md' },
|
||||
{ text: 'Профиль приложений', link: '/ru_RU/guide/app-profile.md' },
|
||||
{ text: 'Выход из циклической загрузки', link: '/ru_RU/guide/rescue-from-bootloop.md' },
|
||||
{ text: 'FAQ', link: '/ru_RU/guide/faq' },
|
||||
{ text: 'Скрытые возможности', link: '/ru_RU/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'vi-VN',
|
||||
description: 'Một giải pháp root trực tiếp trên kernel dành cho các thiết bị hỗ trợ GKI.',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: 'cập nhật lần cuối',
|
||||
|
||||
sidebar: {
|
||||
'/vi_VN/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: 'Phát hành dưới giấy phép GPL3.',
|
||||
copyright: 'Bản Quyền © 2022-nay KernelSU developers.'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: 'Chỉnh sửa trang này trên GitHub'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: 'Hướng Dẫn', link: '/vi_VN/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Hướng Dẫn',
|
||||
items: [
|
||||
{ text: 'KernelSU là gì?', link: '/vi_VN/guide/what-is-kernelsu' },
|
||||
{ text: 'Cách cài đặt', link: '/vi_VN/guide/installation' },
|
||||
{ text: 'Cách để build?', link: '/vi_VN/guide/how-to-build' },
|
||||
{ text: 'Tích hợp vào thiết bị không sử dụng GKI', link: '/vi_VN/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: 'Thiết bị hỗ trợ không chính thức', link: '/vi_VN/guide/unofficially-support-devices.md' },
|
||||
{ text: 'FAQ - Câu hỏi thường gặp', link: '/vi_VN/guide/faq' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'zh-CN',
|
||||
description: '一个基于内核,为安卓 GKI 准备的 root 方案。',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: '最后更新',
|
||||
|
||||
sidebar: {
|
||||
'/zh_CN/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: '在 GPL3 许可证下发布。',
|
||||
copyright: 'Copyright © 2022-现在 KernelSU 开发者。'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: '在 GitHub 中编辑本页'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: '指南', link: '/zh_CN/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: '什么是 KernelSU?', link: '/zh_CN/guide/what-is-kernelsu' },
|
||||
{ text: 'KernelSU 模块与 Magisk 的差异', link: '/zh_CN/guide/difference-with-magisk' },
|
||||
{ text: '安装', link: '/zh_CN/guide/installation' },
|
||||
{ text: '如何构建?', link: '/zh_CN/guide/how-to-build' },
|
||||
{ text: '如何为非 GKI 设备集成 KernelSU', link: '/zh_CN/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: '非官方支持设备', link: '/zh_CN/guide/unofficially-support-devices.md' },
|
||||
{ text: '模块开发指南', link: '/zh_CN/guide/module.md' },
|
||||
{ text: '模块 Web 界面', link: '/zh_CN/guide/module-webui.md' },
|
||||
{ text: 'App Profile', link: '/zh_CN/guide/app-profile.md' },
|
||||
{ text: '救砖', link: '/zh_CN/guide/rescue-from-bootloop.md' },
|
||||
{ text: '常见问题', link: '/zh_CN/guide/faq' },
|
||||
{ text: '隐藏功能', link: '/zh_CN/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { createRequire } from 'module'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('vitepress/package.json')
|
||||
|
||||
export default defineConfig({
|
||||
lang: 'zh-TW',
|
||||
description: '一個基於核心,適用於 Android GKI 的 Root 解決方案。',
|
||||
|
||||
themeConfig: {
|
||||
nav: nav(),
|
||||
|
||||
lastUpdatedText: '上次更新',
|
||||
|
||||
sidebar: {
|
||||
'/zh_TW/guide/': sidebarGuide()
|
||||
},
|
||||
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/tiann/KernelSU' }
|
||||
],
|
||||
|
||||
footer: {
|
||||
message: '係依據 GPL3 授權發行。',
|
||||
copyright: 'Copyright © 2022-目前 KernelSU 開發人員。'
|
||||
},
|
||||
|
||||
editLink: {
|
||||
pattern: 'https://github.com/tiann/KernelSU/edit/main/website/docs/:path',
|
||||
text: '在 GitHub 中編輯本頁面'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function nav() {
|
||||
return [
|
||||
{ text: '指南', link: '/zh_TW/guide/what-is-kernelsu' },
|
||||
]
|
||||
}
|
||||
|
||||
function sidebarGuide() {
|
||||
return [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: '什麼是 KernelSU?', link: '/zh_TW/guide/what-is-kernelsu' },
|
||||
{ text: 'KernelSU 與 Magisk 的差異', link: '/zh_TW/guide/difference-with-magisk' },
|
||||
{ text: '安裝', link: '/zh_TW/guide/installation' },
|
||||
{ text: '如何建置?', link: '/zh_TW/guide/how-to-build' },
|
||||
{ text: '如何為非 GKI 核心整合 KernelSU', link: '/zh_TW/guide/how-to-integrate-for-non-gki'},
|
||||
{ text: '非官方支援裝置', link: '/zh_TW/guide/unofficially-support-devices.md' },
|
||||
{ text: '模組指南', link: '/zh_TW/guide/module.md' },
|
||||
{ text: '模組 WebUI', link: '/zh_TW/guide/module-webui.md' },
|
||||
{ text: 'App Profile', link: '/zh_TW/guide/app-profile.md' },
|
||||
{ text: '搶救開機迴圈', link: '/zh_TW/guide/rescue-from-bootloop.md' },
|
||||
{ text: '常見問題', link: '/zh_TW/guide/faq' },
|
||||
{ text: '隱藏功能', link: '/zh_TW/guide/hidden-features' },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
# App Profile
|
||||
|
||||
The App Profile is a mechanism provided by KernelSU for customizing the configuration of various apps.
|
||||
|
||||
For apps granted root permissions (i.e., able to use `su`), the App Profile can also be referred to as the Root Profile. It allows customization of the `uid`, `gid`, `groups`, `capabilities`, and `SELinux` rules of the `su` command, thereby restricting the privileges of the root user. For example, it can grant network permissions only to firewall apps while denying file access permissions, or it can grant shell permissions instead of full root access for freeze apps: **keeping the power confined with the principle of least privilege.**
|
||||
|
||||
For ordinary apps without root permissions, the App Profile can control the behavior of the kernel and module system towards these apps. For instance, it can determine whether modifications resulting from modules should be addressed. The kernel and module system can make decisions based on this configuration, such as performing operations akin to "hiding".
|
||||
|
||||
## Root Profile
|
||||
|
||||
### UID, GID, and Groups
|
||||
|
||||
Linux systems have two concepts: users and groups. Each user has a user ID (UID), and a user can belong to multiple groups, each with its own group ID (GID). These IDs are used to identify users in the system and determine which system resources they can access.
|
||||
|
||||
Users with a UID of 0 are known as root users, and groups with a GID of 0 are known as root groups. The root user group generally has the highest system privileges.
|
||||
|
||||
In the case of the Android system, each app functions as a separate user (except in cases of shared UIDs) with a unique UID. For example, `0` represents the root user, `1000` represents `system`, `2000` represents the ADB shell, and UIDs ranging from `10000` to `19999` represent ordinary apps.
|
||||
|
||||
::: info
|
||||
Here, the UID mentioned isn't the same as the concept of multiple users or work profiles in the Android system. Work profiles are actually implemented by partitioning the UID range. For example, 10000-19999 represents the main user, while 110000-119999 represents a work profile. Each ordinary app among them has its own unique UID.
|
||||
:::
|
||||
|
||||
Each app can have several groups, with the GID representing the primary group, which usually matches the UID. Other groups are known as supplementary groups. Certain permissions are controlled through groups, such as network access permissions or Bluetooth access.
|
||||
|
||||
For example, if we execute the `id` command in ADB shell, the output might look like this:
|
||||
|
||||
```sh
|
||||
oriole:/ $ id
|
||||
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0
|
||||
```
|
||||
|
||||
Here, the UID is `2000`, and the GID (primary group ID) is also `2000`. Additionally, it belongs to several supplementary groups, such as `inet` (indicating the ability to create `AF_INET` and `AF_INET6` sockets) and `sdcard_rw` (indicating read/write permissions for the SD card).
|
||||
|
||||
KernelSU's Root Profile allows customization of the UID, GID, and groups for the root process after executing `su`. For example, the Root Profile of a root app can set its UID to `2000`, which means that when using `su`, the app's actual permissions are at the ADB shell level. Additionally, the `inet` group can be removed, preventing the `su` command from accessing the network.
|
||||
|
||||
::: tip NOTE
|
||||
The App Profile only controls the permissions of the root process after using `su` and doesn't control the app's own permissions. If an app has requested network access permission, it can still access the network even without using `su`. Removing the `inet` group from `su` only prevents `su` from accessing the network.
|
||||
:::
|
||||
|
||||
Root Profile is enforced in the kernel and doesn't rely on the voluntary behavior of root apps, unlike switching users or groups through `su`. Granting `su` permissions is entirely controlled by the user, not the developer.
|
||||
|
||||
### Capabilities
|
||||
|
||||
Capabilities are a mechanism for privilege separation in Linux.
|
||||
|
||||
For the purpose of performing permission checks, traditional `UNIX` implementations distinguish two categories of processes: privileged processes (whose effective user ID is `0`, referred to as superuser or root) and unprivileged processes (whose effective UID is nonzero). Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (usually: effective UID, effective GID, and supplementary group list).
|
||||
|
||||
Starting with Linux 2.2, Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled and disabled.
|
||||
|
||||
Each capability represents one or more privileges. For example, `CAP_DAC_READ_SEARCH` represents the ability to bypass permission checks for file reading, as well as directory read and execute permissions. If a user with an effective UID of `0` (root user) doesn't have the `CAP_DAC_READ_SEARCH` capability or higher, this means that even as root, they cannot freely read files.
|
||||
|
||||
KernelSU's Root Profile allows customization of the capabilities of the root process after executing `su`, thus granting partial "root privileges". Unlike the UID and GID mentioned above, certain root apps require a UID of `0` after using `su`. In such cases, limiting the capabilities of this root user with UID `0` can restrict the operations they're allowed to perform.
|
||||
|
||||
::: tip STRONG RECOMMENDATION
|
||||
Linux's capability [official documentation](https://man7.org/linux/man-pages/man7/capabilities.7.html) provides detailed explanations of the abilities represented by each capability. If you intend to customize capabilities, it's strongly recommended that you read this document first.
|
||||
:::
|
||||
|
||||
### SELinux
|
||||
|
||||
SELinux is a powerful Mandatory Access Control (MAC) mechanism. It operates on the principle of **default deny**. Any action not explicitly allowed is denied.
|
||||
|
||||
SELinux can run in two global modes:
|
||||
|
||||
1. Permissive mode: Denial events are logged, but not enforced.
|
||||
2. Enforcing mode: Denial events are logged and enforced.
|
||||
|
||||
::: warning
|
||||
Modern Android systems heavily rely on SELinux to ensure overall system security. It's highly recommended not to use any custom systems running in "Permissive mode" since it provides no significant advantages over a completely open system.
|
||||
:::
|
||||
|
||||
Explaining the full concept of SELinux is complex and beyond the scope of this document. It's recommended to first understand how it works through the following resources:
|
||||
|
||||
1. [Wikipedia](https://en.wikipedia.org/wiki/Security-Enhanced_Linux)
|
||||
2. [Red Hat: What Is SELinux?](https://www.redhat.com/en/topics/linux/what-is-selinux)
|
||||
3. [ArchLinux: SELinux](https://wiki.archlinux.org/title/SELinux)
|
||||
|
||||
KernelSU's Root Profile allows customization of the SELinux context of the root process after executing `su`. Specific access control rules can be set for this context, enabling fine-grained control over root permissions.
|
||||
|
||||
In typical scenarios, when an app executes `su`, it switches the process to a SELinux domain with **unrestricted access**, such as `u:r:su:s0`. Through the Root Profile, this domain can be switched to a custom domain, such as `u:r:app1:s0`, and a series of rules can be defined for this domain:
|
||||
|
||||
```sh
|
||||
type app1
|
||||
enforce app1
|
||||
typeattribute app1 mlstrustedsubject
|
||||
allow app1 * * *
|
||||
```
|
||||
|
||||
Note that the `allow app1 * * *` rule is used for demonstration purposes only. In practice, this rule shouldn't be used extensively, as it isn't much different from Permissive mode.
|
||||
|
||||
### Escalation
|
||||
|
||||
If the configuration of the Root Profile isn't set properly, an escalation scenario may occur. The restrictions imposed by the Root Profile can unintentionally fail.
|
||||
|
||||
For example, if you grant root permission to an ADB shell user (which is a common case) and then grant root permission to a regular app, but configure its Root Profile with UID 2000 (which is the UID of the ADB shell user), the app can obtain full root access by executing the `su` command twice:
|
||||
|
||||
1. The first execution of `su` will be subject to the App Profile and will switch to UID `2000` (ADB shell) instead of `0` (root).
|
||||
2. The second execution of `su`, since the UID is `2000` and root access has been granted to UID `2000` (ADB shell) in the configuration, the app will gain full root privileges.
|
||||
|
||||
::: warning NOTE
|
||||
This behavior is fully expected and isn't a bug. Therefore, we recommend the following:
|
||||
|
||||
If you genuinely need to grant root permissions to ADB (e.g., as a developer), it isn't advisable to change the UID to `2000` when configuring the Root Profile. Using `1000` (system) would be a better choice.
|
||||
:::
|
||||
|
||||
## Non-root profile
|
||||
|
||||
### Umount modules
|
||||
|
||||
KernelSU provides a systemless mechanism to modify system partitions, achieved through the mounting of OverlayFS. However, some apps may be sensitive to this behavior. In this case, we can unload modules mounted in these apps by setting the "Umount modules" option.
|
||||
|
||||
Additionally, the KernelSU manager's settings interface provides the "Umount modules by default". By default, this option is **enabled**, which means that KernelSU or some modules will unload modules for this app unless additional settings are applied. If you don't prefer this setting or if it affects certain apps, you have the following options:
|
||||
|
||||
1. Keep the "Umount modules by default" option enabled and individually disable the "Umount modules" option in the App Profile for apps requiring module loading (acting as a "whitelist").
|
||||
2. Disable the "Umount modules by default" option and individually enable the "Umount modules" option in the App Profile for apps requiring module loading (acting as a "blacklist").
|
||||
|
||||
::: info
|
||||
In devices running kernel version 5.10 and above, the kernel performs without any further action the unloading of modules. However, for devices running kernel versions below 5.10, this option is merely a configuration setting, and KernelSU itself doesn't take any action. If you want to use the "Umount modules" option in kernel versions before 5.10 you need to backport the `path_umount` function in `fs/namespace.c`. You can get more information at the end of the [Intergrate for non-GKI devices](https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path_umount) page. Some modules, such as Zygisksu, may also use this option to determine if module unloading is necessary.
|
||||
:::
|
||||
@@ -1,28 +0,0 @@
|
||||
# Difference with Magisk
|
||||
|
||||
Although KernelSU and Magisk modules have many similarities, there are inevitably some differences due to their completely different implementation mechanisms. If you want your module to work on both Magisk and KernelSU, it's essential to understand these differences.
|
||||
|
||||
## Similarities
|
||||
|
||||
- Module file format: Both use the ZIP format to organize modules, and the module format is practically the same.
|
||||
- Module installation directory: Both are located at `/data/adb/modules`.
|
||||
- Systemless: Both support modifying `/system` in a systemless way through modules.
|
||||
- post-fs-data.sh: Execution time and semantics are exactly the same.
|
||||
- service.sh: Execution time and semantics are exactly the same.
|
||||
- system.prop: Completely the same.
|
||||
- sepolicy.rule: Completely the same.
|
||||
- BusyBox: Scripts are run in BusyBox with "Standalone Mode" enabled in both cases.
|
||||
|
||||
## Differences
|
||||
|
||||
Before understanding the differences, it's important to know how to identify whether your module is running in KernelSU or Magisk. You can use the environment variable `KSU` to differentiate it in all places where you can run module scripts (`customize.sh`, `post-fs-data.sh`, `service.sh`). In KernelSU, this environment variable will be set to `true`.
|
||||
|
||||
Here are some differences:
|
||||
|
||||
- KernelSU modules cannot be installed in Recovery mode.
|
||||
- KernelSU modules don't have built-in support for Zygisk, but you can use Zygisk modules through [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext)).
|
||||
- The method for replacing or deleting files in KernelSU modules is completely different from Magisk. KernelSU doesn't support the `.replace` method. Instead, you need to create a same-named file with `mknod filename c 0 0` to delete the corresponding file.
|
||||
- The directories for BusyBox are different. The built-in BusyBox in KernelSU is located at `/data/adb/ksu/bin/busybox`, while in Magisk it is at `/data/adb/magisk/busybox`. **Note that this is an internal behavior of KernelSU and may change in the future!**
|
||||
- KernelSU doesn't support `.replace` files, but it supports the `REMOVE` and `REPLACE` variables to remove or replace files and folders.
|
||||
- KernelSU adds the `boot-completed` stage to run scripts after the boot process is finished.
|
||||
- KernelSU adds the `post-mount` stage to run scripts after OverlayFS is mounted.
|
||||
@@ -1,78 +0,0 @@
|
||||
# FAQ
|
||||
|
||||
## Does KernelSU support my device?
|
||||
|
||||
First, your devices should be able to unlock the bootloader. If not, then there is unsupported.
|
||||
|
||||
Next, install the KernelSU manager on your device and open it. If it shows `Unsupported`, then your device cannot be supported immediately. However, you can build kernel source and integrate KernelSU to make it work, or use [Unofficially supported devices](unofficially-support-devices).
|
||||
|
||||
## Does KernelSU need to unlock bootloader?
|
||||
|
||||
Certainly, yes.
|
||||
|
||||
## Does KernelSU support modules?
|
||||
|
||||
Yes, check [Module guide](module.md).
|
||||
|
||||
## Does KernelSU support Xposed?
|
||||
|
||||
Yes, you can use LSPosed with [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## Does KernelSU support Zygisk?
|
||||
|
||||
KernelSU has no built-in Zygisk support, but you can use [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## Is KernelSU compatible with Magisk?
|
||||
|
||||
KernelSU's module system conflicts with Magisk's magic mount. If any module is enabled in KernelSU, Magisk will stop working entirely.
|
||||
|
||||
However, if you only use the `su` of KernelSU, it will work well with Magisk. KernelSU modifies the `kernel`, while Magisk modifies the `ramdisk`, allowing both to work together.
|
||||
|
||||
## Will KernelSU substitute Magisk?
|
||||
|
||||
We believe that it isn't, and that isn't our goal. Magisk is good enough for userspace root solution and will have a long life. KernelSU's goal is to provide a kernel interface to users, not substituting Magisk.
|
||||
|
||||
## Can KernelSU support non-GKI devices?
|
||||
|
||||
It's possible. But you should download the kernel source and intergrate KernelSU into the source tree, and compile the kernel yourself.
|
||||
|
||||
## Can KernelSU support devices below Android 12?
|
||||
|
||||
It's the device's kernel that affects KernelSU's compatibility, and it has nothing to do with the Android version. The only restriction is that devices launched with Android 12 must have a kernel version of 5.10+ (GKI devices). So:
|
||||
|
||||
1. Devices launched with Android 12 must be supported.
|
||||
2. Devices with an older kernel (some devices with Android 12 also have the older kernel) are compatible (you should build kernel yourself).
|
||||
|
||||
## Can KernelSU support old kernel?
|
||||
|
||||
It's possible. KernelSU is backported to kernel 4.14 now. For older kernels, you need to backport it manually, and PRs are always welcome!
|
||||
|
||||
## How to integrate KernelSU for an older kernel?
|
||||
|
||||
Please check the [Intergrate for non-GKI devices](how-to-integrate-for-non-gki) guide.
|
||||
|
||||
## Why my Android version is 13, and the kernel shows "android12-5.10"?
|
||||
|
||||
The kernel version has nothing to do with the Android version. If you need to flash kernel, always use the kernel version; the Android version isn't as important.
|
||||
|
||||
## I'm GKI 1.0, can I use this?
|
||||
|
||||
GKI 1.0 is completely different from GKI 2.0, you must compile kernel by yourself.
|
||||
|
||||
## How can I make `/system` RW?
|
||||
|
||||
We don't recommend that you modify the system partition directly. Please check [Module guide](module.md) to modify it systemlessly. If you insist on doing this, check [magisk_overlayfs](https://github.com/HuskyDG/magic_overlayfs).
|
||||
|
||||
## Can KernelSU modify hosts? How can I use AdAway?
|
||||
|
||||
Of course. But KernelSU doesn't have built-in hosts support, you can install [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) to do it.
|
||||
|
||||
## Why is there a huge 1 TB file?
|
||||
|
||||
The 1 TB `modules.img` file is a disk image file. **Don't worry about its size**; it's a special type of file known as a [sparse file](https://en.wikipedia.org/wiki/Sparse_file). Its actual size is only the size of the module you use, and it will decrease dynamically after you delete the module. In fact, it doesn't occupy 1 TB of disk space (your device might not even have that much space).
|
||||
|
||||
If you really care about the size of this file, you can use the `resize2fs -M` command to make it the actual size. However, the module may not work correctly in this case, and we won't provide any support for this.
|
||||
|
||||
## Why does my device show wrong storage size?
|
||||
|
||||
Certain devices use non-standard methods to calculate the device's storage size, which may lead to inaccurate storage calculations in system apps and menus, especially when dealing with 1 TB sparse files. Although this problem seems to be specific to Samsung devices, affecting only Samsung apps and services, it's important to note that the discrepancy mainly concerns the total storage size, and the free space calculation remains accurate.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Hidden features
|
||||
|
||||
## .ksurc
|
||||
|
||||
By default, `/system/bin/sh` loads `/system/etc/mkshrc`.
|
||||
|
||||
You can make su load customized rc file by creating a `/data/adb/ksu/.ksurc` file.
|
||||
@@ -1,71 +0,0 @@
|
||||
# How to build
|
||||
|
||||
First, you should read the official Android documentation for kernel build:
|
||||
|
||||
1. [Build kernels](https://source.android.com/docs/setup/build/building-kernels)
|
||||
2. [GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
::: warning
|
||||
This page is for GKI devices, if you use an old kernel, please refer [Intergrate for non-GKI devices](how-to-integrate-for-non-gki).
|
||||
:::
|
||||
|
||||
## Build kernel
|
||||
|
||||
### Sync the kernel source code
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
The `<kernel_manifest.xml>` file is a manifest that uniquely identifies a build, allowing you to make it reproducible. To do this, you should download the manifest file from [GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds).
|
||||
|
||||
### Build
|
||||
|
||||
Please check the [Building kernels](https://source.android.com/docs/setup/build/building-kernels) first.
|
||||
|
||||
For example, to build an `aarch64` kernel image:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Don't forget to add the `LTO=thin` flag; otherwise, the build may fail if your computer has less than 24 GB of memory.
|
||||
|
||||
Starting from Android 13, the kernel is built by `bazel`:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
|
||||
::: info
|
||||
For some Android 14 kernels, to make Wi-Fi/Bluetooth work, it might be necessary to remove all GKI protected exports:
|
||||
|
||||
```sh
|
||||
rm common/android/abi_gki_protected_exports_*
|
||||
```
|
||||
:::
|
||||
|
||||
## Build kernel with KernelSU
|
||||
|
||||
If you can successfully build the kernel, adding support for KernelSU will be relatively easy. In the root of kernel source directory, run any of the options listed below:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh[Latest tag (stable)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
```sh[ main branch (dev)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
```sh[Select tag (such as v0.5.2)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Then, rebuild the kernel and you will get a kernel image with KernelSU!
|
||||
@@ -1,377 +0,0 @@
|
||||
# Intergrate for non-GKI devices
|
||||
|
||||
KernelSU can be integrated into non-GKI kernels and was backported to 4.14 and earlier versions.
|
||||
|
||||
Due to the fragmentation of non-GKI kernels, we don't have a universal method to build it, so we cannot provide the non-GKI boot.img. However, you can build the kernel with KernelSU integrated on your own.
|
||||
|
||||
First, you should be able to build a bootable kernel from kernel source code. If the kernel isn't open source, then it is difficult to run KernelSU for your device.
|
||||
|
||||
If you're able to build a bootable kernel, there are two ways to integrate KernelSU into the kernel source code:
|
||||
|
||||
1. Automatically with `kprobe`
|
||||
2. Manually
|
||||
|
||||
## Integrate with kprobe
|
||||
|
||||
KernelSU uses kprobe to do kernel hooks, if kprobe runs well in your kernel, it's recommended to use it this way.
|
||||
|
||||
First, add KernelSU to your kernel source tree:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
::: info
|
||||
[KernelSU 1.0 and later versions no longer support non-GKI kernels](https://github.com/tiann/KernelSU/issues/1705). The last supported version is `v0.9.5`, so make sure to use the correct version.
|
||||
:::
|
||||
|
||||
Then, you should check if kprobe is enabled in your kernel config. If it isn't, add these configs to it:
|
||||
|
||||
```txt
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
Now, when you re-build your kernel, KernelSU should work correctly.
|
||||
|
||||
If you find that KPROBES is still not enabled, you can try enabling `CONFIG_MODULES`. If that doesn't solve the issue, use `make menuconfig` to search for other KPROBES dependencies.
|
||||
|
||||
However, if you encounter a bootloop after integrating KernelSU, this may indicate that the **kprobe is broken in your kernel**, which means that you should fix the kprobe bug or use another way.
|
||||
|
||||
::: tip HOW TO CHECK IF KPROBE IS BROKEN?
|
||||
Comment out `ksu_enable_sucompat()` and `ksu_enable_ksud()` in `KernelSU/kernel/ksu.c`, if the device boots normally, then kprobe may be broken.
|
||||
:::
|
||||
|
||||
::: info HOW TO GET MODULE UMOUNT FEATURE WORKING ON PRE-GKI?
|
||||
If your kernel is older than 5.9, you should backport `path_umount` to `fs/namespace.c`. This is required to get "Umount module" feature work correctly. If you don't backport `path_umount`, "Umount module" feature won't work. You can get more info on how to achieve this at the end of this page.
|
||||
:::
|
||||
|
||||
## Manually modify the kernel source
|
||||
|
||||
If kprobe doesn't work on your kernel this may be caused by an upstream bug or if the kernel is below 4.8), then you can try the following:
|
||||
|
||||
First, add KernelSU to your kernel source tree:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
Keep in mind that, on some devices, your defconfig may be located at `arch/arm64/configs` or in other cases, it may be at `arch/arm64/configs/vendor/your_defconfig`. Regardless of the defconfig you're using, make sure to enable `CONFIG_KSU` with `y` to enable or `n` to disable it. For example, if you choose to enable it, your defconfig should contain the following string:
|
||||
|
||||
```txt
|
||||
# KernelSU
|
||||
CONFIG_KSU=y
|
||||
```
|
||||
|
||||
Next, add KernelSU calls to the kernel source. Below are some patches for reference:
|
||||
|
||||
::: code-group
|
||||
|
||||
```diff[exec.c]
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
+#endif
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ #endif
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff[open.c]
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff[read_write.c]
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
+#endif
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+ #endif
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff[stat.c]
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Get basic and extra attributes by filename
|
||||
* @dfd: A file descriptor representing the base dir for a relative filename
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
+ #endif
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
You should find the four functions in kernel source:
|
||||
|
||||
1. `do_faccessat`, usually in `fs/open.c`
|
||||
2. `do_execveat_common`, usually in `fs/exec.c`
|
||||
3. `vfs_read`, usually in `fs/read_write.c`
|
||||
4. `vfs_statx`, usually in `fs/stat.c`
|
||||
|
||||
If your kernel doesn't have the `vfs_statx` function, use `vfs_fstatat` instead:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fstat);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int flag)
|
||||
{
|
||||
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = 0;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||
+ #endif
|
||||
+
|
||||
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH)) != 0)
|
||||
goto out;
|
||||
```
|
||||
|
||||
For kernels eariler than 4.17, if you cannot find `do_faccessat`, just go to the definition of the `faccessat` syscall and place the call there:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 2ff887661237..e758d7db7663 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return error;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
+
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
### Safe Mode
|
||||
|
||||
To enable KernelSU's built-in Safe Mode, you should modify the `input_handle_event` function in `drivers/input/input.c`:
|
||||
|
||||
::: tip
|
||||
It's strongly recommended to enable this feature, it's very useful for preventing bootloops!
|
||||
:::
|
||||
|
||||
```diff
|
||||
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
||||
index 45306f9ef247..815091ebfca4 100755
|
||||
--- a/drivers/input/input.c
|
||||
+++ b/drivers/input/input.c
|
||||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev,
|
||||
return disposition;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_input_hook __read_mostly;
|
||||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);
|
||||
+#endif
|
||||
+
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition = input_get_disposition(dev, type, code, &value);
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_input_hook))
|
||||
+ ksu_handle_input_handle_event(&type, &code, &value);
|
||||
+ #endif
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
::: info ENTERING SAFE MODE ACCIDENTALLY?
|
||||
If you're using manual integration and don't disable `CONFIG_KPROBES`, the user will be able to trigger Safe Mode by pressing the volume down button after booting! Therefore, if you're using manual integration, it's necessary to disable `CONFIG_KPROBES`!
|
||||
:::
|
||||
|
||||
### Failed to execute `pm` in terminal?
|
||||
|
||||
You should modify `fs/devpts/inode.c`. Reference:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
|
||||
index 32f6f1c68..d69d8eca2 100644
|
||||
--- a/fs/devpts/inode.c
|
||||
+++ b/fs/devpts/inode.c
|
||||
@@ -602,6 +602,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
return dentry;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_devpts(struct inode*);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* devpts_get_priv -- get private data for a slave
|
||||
* @pts_inode: inode of the slave
|
||||
@@ -610,6 +612,7 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
*/
|
||||
void *devpts_get_priv(struct dentry *dentry)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_devpts(dentry->d_inode);
|
||||
+ #endif
|
||||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC)
|
||||
return NULL;
|
||||
return dentry->d_fsdata;
|
||||
```
|
||||
|
||||
### How to backport path_umount
|
||||
|
||||
You can make the "Umount modules" feature work on pre-GKI kernels by manually backporting `path_umount` from 5.9. You can use this patch as reference:
|
||||
|
||||
```diff
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1739,6 +1739,39 @@ static inline bool may_mandlock(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
+static int can_umount(const struct path *path, int flags)
|
||||
+{
|
||||
+ struct mount *mnt = real_mount(path->mnt);
|
||||
+
|
||||
+ if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
|
||||
+ return -EINVAL;
|
||||
+ if (!may_mount())
|
||||
+ return -EPERM;
|
||||
+ if (path->dentry != path->mnt->mnt_root)
|
||||
+ return -EINVAL;
|
||||
+ if (!check_mnt(mnt))
|
||||
+ return -EINVAL;
|
||||
+ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
|
||||
+ return -EINVAL;
|
||||
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
|
||||
+ return -EPERM;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int path_umount(struct path *path, int flags)
|
||||
+{
|
||||
+ struct mount *mnt = real_mount(path->mnt);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = can_umount(path, flags);
|
||||
+ if (!ret)
|
||||
+ ret = do_umount(mnt, flags);
|
||||
+
|
||||
+ /* we mustn't call path_put() as that would clear mnt_expiry_mark */
|
||||
+ dput(path->dentry);
|
||||
+ mntput_no_expire(mnt);
|
||||
+ return ret;
|
||||
+}
|
||||
/*
|
||||
* Now umount can handle mount points as well as block devices.
|
||||
* This is important for filesystems which use unnamed block devices.
|
||||
```
|
||||
|
||||
Finally, build your kernel again, and KernelSU should work correctly.
|
||||
@@ -1,280 +0,0 @@
|
||||
# Installation
|
||||
|
||||
## Check if your device is supported
|
||||
|
||||
Download KernelSU manager from [GitHub Releases](https://github.com/tiann/KernelSU/releases) and install it on your device:
|
||||
|
||||
- If the app shows `Unsupported`, it means that **you should compile the kernel yourself**, KernelSU won't and never provide a boot.img file for you to flash.
|
||||
- If the app shows `Not installed`, then your device is officially supported by KernelSU.
|
||||
|
||||
::: info
|
||||
For devices showing `Unsupported`, you can check the list of [Unofficially supported devices](unofficially-support-devices.md). You can compile the kernel yourself.
|
||||
:::
|
||||
|
||||
## Backup stock boot.img
|
||||
|
||||
Before flashing, it's essential that you back up your stock boot.img. If you encounter any bootloop, you can always restore the system by flashing back to the stock factory boot using fastboot.
|
||||
|
||||
::: warning
|
||||
Flashing may cause data loss. Make sure to do this step well before proceeding to the next step! You can also back up all the data on your device if necessary.
|
||||
:::
|
||||
|
||||
## Necessary knowledge
|
||||
|
||||
### ADB and fastboot
|
||||
|
||||
By default, you will use ADB and fastboot tools in this tutorial, so if you don't know them, we recommend using a search engine to learn about them first.
|
||||
|
||||
### KMI
|
||||
|
||||
Kernel Module Interface (KMI), kernel versions with the same KMI are **compatible**, this is what "general" means in GKI; conversely, if the KMI is different, then these kernels aren't compatible with each other, and flashing a kernel image with a different KMI than your device may cause a bootloop.
|
||||
|
||||
Specifically, for GKI devices, the kernel version format should be as follows:
|
||||
|
||||
```txt
|
||||
KernelRelease :=
|
||||
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
|
||||
w .x .y -zzz -k -something
|
||||
```
|
||||
|
||||
`w.x-zzz-k` is the KMI version. For example, if a device kernel version is `5.10.101-android12-9-g30979850fc20`, then its KMI is `5.10-android12-9`. Theoretically, it can boot up normally with other KMI kernels.
|
||||
|
||||
::: tip
|
||||
Note that the SubLevel in the kernel version isn't part of the KMI! This means that `5.10.101-android12-9-g30979850fc20` has the same KMI as `5.10.137-android12-9-g30979850fc20`!
|
||||
:::
|
||||
|
||||
### Security patch level {#security-patch-level}
|
||||
|
||||
Newer Android devices may have anti-rollback mechanisms that prevent flashing a boot image with an old security patch level. For example, if your device kernel is `5.10.101-android12-9-g30979850fc20`, the security patch level is `2023-11`; even if you flash the kernel corresponding to the KMI, if the security patch level is older than `2023-11` (such as `2023-06`), it may cause a bootloop.
|
||||
|
||||
Therefore, kernels with latest security patch levels are preferred to maintain compatibility with the KMI.
|
||||
|
||||
### Kernel version vs Android version
|
||||
|
||||
Please note: **Kernel version and Android version aren't necessarily the same!**
|
||||
|
||||
If you find that your kernel version is `android12-5.10.101`, but your Android system version is Android 13 or other, don't be surprised, because the version number of the Android system isn't necessarily the same as the version number of the Linux kernel. The version number of the Linux kernel is generally correspondent to the version of the Android system that comes with the **device when it is shipped**. If the Android system is upgraded later, the kernel version will generally not change. So, before flashing anything, **always refer to the kernel version!**
|
||||
|
||||
## Introduction
|
||||
|
||||
Since version [0.9.0](https://github.com/tiann/KernelSU/releases/tag/v0.9.0), KernelSU supports two running modes on GKI devices:
|
||||
|
||||
1. `GKI`: Replace the original kernel of the device with the **Generic Kernel Image** (GKI) provided by KernelSU.
|
||||
2. `LKM`: Load the **Loadable Kernel Module** (LKM) into the device kernel without replacing the original kernel.
|
||||
|
||||
These two modes are suitable for different scenarios, and you can choose the one according to your needs.
|
||||
|
||||
### GKI mode {#gki-mode}
|
||||
|
||||
In GKI mode, the original kernel of the device will be replaced with the generic kernel image provided by KernelSU. The advantages of GKI mode are:
|
||||
|
||||
1. Strong universality, suitable for most devices. For example, Samsung has enabled KNOX devices, and LKM mode cannot work. There are also some niche modified devices that can only use GKI mode.
|
||||
2. Can be used without relying on official firmware, and there is no need to wait for official firmware updates, as long as the KMI is consistent, it can be used.
|
||||
|
||||
### LKM mode {#lkm-mode}
|
||||
|
||||
In LKM mode, the original kernel of the device won't be replaced, but the loadable kernel module will be loaded into the device kernel. The advantages of LKM mode are:
|
||||
|
||||
1. Won't replace the original kernel of the device. If you have special requirements for the original kernel of the device, or you want to use KernelSU while using a third-party kernel, you can use LKM mode.
|
||||
2. It's more convenient to upgrade and OTA. When upgrading KernelSU, you can directly install it in the manager without flashing manually. After the system OTA, you can directly install it to the second slot without manual flashing.
|
||||
3. Suitable for some special scenarios. For example, LKM can also be loaded with temporary root permissions. Since it doesn't need to replace the boot partition, it won't trigger AVB and won't cause the device to be bricked.
|
||||
4. LKM can be temporarily uninstalled. If you want to temporarily disable root access, you can uninstall LKM. This process doesn't require flashing partitions, or even rebooting the device. If you want to enable root again, just reboot the device.
|
||||
|
||||
::: tip COEXISTENCE OF TWO MODES
|
||||
After opening the manager, you can see the current mode of the device on the homepage. Note that the priority of GKI mode is higher than that of LKM. For example, if you use GKI kernel to replace the original kernel, and use LKM to patch the GKI kernel, the LKM will be ignored, and the device will always run in GKI mode.
|
||||
:::
|
||||
|
||||
### Which one to choose? {#which-one}
|
||||
|
||||
If your device is a mobile phone, we recommend that you prioritize LKM mode. If your device is an emulator, WSA, or Waydroid, we recommend that you prioritize GKI mode.
|
||||
|
||||
## LKM installation
|
||||
|
||||
### Get the official firmware
|
||||
|
||||
To use LKM mode, you need to get the official firmware and patch it based on the official firmware. If you use a third-party kernel, you can use the `boot.img` of the third-party kernel as the official firmware.
|
||||
|
||||
There are many ways to get the official firmware. If your device supports `fastboot boot`, we recommend **the most recommended and simplest** method is to use `fastboot boot` to temporarily boot the GKI kernel provided by KernelSU, then install the manager, and finally install it directly in the manager. This method doesn't require manually downloading the official firmware or manually extracting the boot.
|
||||
|
||||
If your device doesn't support `fastboot boot`, you may need to manually download the official firmware package and extract the boot from it.
|
||||
|
||||
Unlike GKI mode, LKM mode modifies the `ramdisk`. Therefore, on devices with Android 13, it needs to patch the `init_boot` partition instead of the `boot` partition, while GKI mode always operates on the `boot` partition.
|
||||
|
||||
### Use the manager
|
||||
|
||||
Open the manager, click the installation icon in the upper right corner, and several options will appear:
|
||||
|
||||
1. Select a file. If your device doesn't have root privileges, you can choose this option and then select your official firmware. The manager will automatically patch it. After that, just flash this patched file to obtain root privileges permanently.
|
||||
2. Direct install. If your device is already rooted, you can choose this option. The manager will automatically get your device information, and then automatically patch the official firmware, and flash it automatically. You can consider using `fastboot boot` KernelSU's GKI kernel to get temporary root and install the manager, and then use this option. This is also the main way to upgrade KernelSU.
|
||||
3. Install to inactive slot. If your device supports A/B partition, you can choose this option. The manager will automatically patch the official firmware and install it to another partition. This method is suitable for devices after OTA, you can directly install it to another partition after OTA, and then restart the device.
|
||||
|
||||
### Use the command line
|
||||
|
||||
If you don't want to use the manager, you can also use the command line to install LKM. The `ksud` tool provided by KernelSU can help you quickly patch the official firmware and then flash it.
|
||||
|
||||
This tool supports macOS, Linux, and Windows. You can download the corresponding version from [GitHub Release](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
Usage: `ksud boot-patch` you can check the command line help for specific options.
|
||||
|
||||
```sh
|
||||
oriole:/ # ksud boot-patch -h
|
||||
Patch boot or init_boot images to apply KernelSU
|
||||
|
||||
Usage: ksud boot-patch [OPTIONS]
|
||||
|
||||
Options:
|
||||
-b, --boot <BOOT> Boot image path. If not specified, it will try to find the boot image automatically
|
||||
-k, --kernel <KERNEL> Kernel image path to be replaced
|
||||
-m, --module <MODULE> LKM module path to be replaced. If not specified, the built-in module will be used
|
||||
-i, --init <INIT> init to be replaced
|
||||
-u, --ota Will use another slot if the boot image is not specified
|
||||
-f, --flash Flash it to boot partition after patch
|
||||
-o, --out <OUT> Output path. If not specified, the current directory will be used
|
||||
--magiskboot <MAGISKBOOT> magiskboot path. If not specified, the built-in version will be used
|
||||
--kmi <KMI> KMI version. If specified, the indicated KMI will be used
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
A few options that need to be explained:
|
||||
|
||||
1. The `--magiskboot` option can specify the path of magiskboot. If not specified, ksud will look for it in the environment variables. If you don’t know how to get magiskboot, you can check [here](#patch-boot-image).
|
||||
2. The `--kmi` option can specify the `KMI` version. If the kernel name of your device doesn't follow the KMI specification, you can specify it using this option.
|
||||
|
||||
The most common usage is:
|
||||
|
||||
```sh
|
||||
ksud boot-patch -b <boot.img> --kmi android13-5.10
|
||||
```
|
||||
|
||||
## GKI mode installation
|
||||
|
||||
There are several installation methods for GKI mode, each suitable for a different scenario, so please choose accordingly:
|
||||
|
||||
1. Install with fastboot using the boot.img provided by KernelSU.
|
||||
2. Install with a kernel flash app, such as [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases).
|
||||
3. Repair the boot.img manually and install it.
|
||||
4. Install with custom Recovery (e.g., TWRP).
|
||||
|
||||
## Install with boot.img provided by KernelSU
|
||||
|
||||
If your device's `boot.img` uses a commonly used compression format, you can use the GKI images provided by KernelSU to flash it directly. This doesn't require TWRP or self-patching the image.
|
||||
|
||||
### Find proper boot.img
|
||||
|
||||
KernelSU provides a generic boot.img for GKI devices, and you should flash the boot.img to the device's boot partition.
|
||||
|
||||
You can download boot.img from [GitHub Release](https://github.com/tiann/KernelSU/releases). Please note that you should use the correct version of boot.img. If you don't know which file to download, carefully read the description of [KMI](#kmi) and [Security patch level](#security-patch-level) in this document.
|
||||
|
||||
Normally, there are three boot files in different formats for the same KMI and security patch level. They're identical except for the kernel compression format. Please check the kernel compression format of your original boot.img. You should use the correct format, such as `lz4`, `gz`. If you use an incorrect compression format, you may encounter bootloop after flashing boot.img.
|
||||
|
||||
::: info COMPRESSION FORMAT OF BOOT.IMG
|
||||
1. You can use magiskboot to get the compression format of your original boot.img. Alternatively, you can also ask members or developers in the community who have the same device model. Also, the compression format of the kernel usually doesn't change, so if you boot successfully with a certain compression format, you can try that format later as well.
|
||||
2. Xiaomi devices usually use `gz` or `uncompressed`.
|
||||
3. For Pixel devices, follow the instructions below:
|
||||
:::
|
||||
|
||||
### Flash boot.img to device
|
||||
|
||||
Use `adb` to connect your device, then execute `adb reboot bootloader` to enter fastboot mode, and use this command to flash KernelSU:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
::: info
|
||||
If your device supports `fastboot boot`, you can first use `fastboot boot boot.img` to try to use boot.img to boot the system first. If something unexpected happens, restart it again to boot.
|
||||
:::
|
||||
|
||||
### Reboot
|
||||
|
||||
After the flash is completed, you should reboot your device:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
## Install with Kernel Flasher
|
||||
|
||||
Steps:
|
||||
|
||||
1. Download the AnyKernel3 ZIP. If you don't know which file to download, carefully read the description of [KMI](#kmi) and [Security patch level](#security-patch-level) in this document.
|
||||
2. Open the Kernel Flasher app, grant necessary root permissions, and use the provided AnyKernel3 ZIP to flash.
|
||||
|
||||
This way requires the Kernel Flasher app to have root permissions. You can use the following methods to achieve this:
|
||||
|
||||
1. Your device is rooted. For example, you have installed KernelSU and want to upgrade to the latest version or you have rooted through other methods (such as Magisk).
|
||||
2. If your device isn't rooted, but the device supports the temporary boot method of `fastboot boot boot.img`, you can use the GKI image provided by KernelSU to temporarily boot your device, obtain temporary root permissions, and then use the Kernel Flash app to obtain permanent root privileges.
|
||||
|
||||
Some of kernel flashing apps that can be used for this:
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
Note: This method is more convenient when upgrading KernelSU and can be done without a computer (make a backup first).
|
||||
|
||||
## Patch boot.img manually {#patch-boot-image}
|
||||
|
||||
For some devices, the boot.img format isn't as common as `lz4`, `gz`, and `uncompressed`. A typical example is the Pixel, where the boot.img is compressed in the `lz4_legacy` format, while the, ramdisk may be in `gz` or also compressed in `lz4_legacy`. Currently, if you directly flash the boot.img provided by KernelSU, the device may not be able to boot. In this case, you can manually patch the boot.img to achieve this.
|
||||
|
||||
It's always recommended to use `magiskboot` to patch images, there are two ways:
|
||||
|
||||
1. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
2. [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci)
|
||||
|
||||
The official build of `magiskboot` can only run on Android devices, if you want to run it on PC, you can try the second option.
|
||||
|
||||
::: tip
|
||||
Android-Image-Kitchen isn't recommended for now because it doesn't handle the boot metadata (such as security patch level) correctly. Therefore, it may not work on some devices.
|
||||
:::
|
||||
|
||||
### Preparation
|
||||
|
||||
1. Get your device's stock boot.img. You can get it from your device manufacturers. You may need [payload-dumper-go](https://github.com/ssut/payload-dumper-go).
|
||||
2. Download the AnyKernel3 ZIP file provided by KernelSU that matches the KMI version of your device. You can refer to [Install with custom Recovery](#install-with-custom-recovery).
|
||||
3. Unpack the AnyKernel3 package and get the `Image` file, which is the kernel file of KernelSU.
|
||||
|
||||
### Using magiskboot on Android devices {#using-magiskboot-on-Android-devices}
|
||||
|
||||
1. Download latest Magisk from [GitHub Releases](https://github.com/topjohnwu/Magisk/releases).
|
||||
2. Rename `Magisk-*(version).apk` to `Magisk-*.zip` and unzip it.
|
||||
3. Push `Magisk-*/lib/arm64-v8a/libmagiskboot.so` to your device by ADB: `adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot`
|
||||
4. Push stock boot.img and Image in AnyKernel3 to your device.
|
||||
5. Enter ADB shell and run `cd /data/local/tmp/` directory, then `chmod +x magiskboot`
|
||||
6. Enter ADB shell and run `cd /data/local/tmp/` directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
7. Replace `kernel` with `Image` by running the command: `mv -f Image kernel`.
|
||||
8. Execute `./magiskboot repack boot.img` to repack boot image, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
|
||||
### Using magiskboot on Windows/macOS/Linux PC {#using-magiskboot-on-PC}
|
||||
|
||||
1. Download the corresponding `magiskboot` binary for your OS from [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci).
|
||||
2. Prepare stock `boot.img` and `Image` in your PC.
|
||||
3. Run `chmod +x magiskboot`.
|
||||
4. Enter the corresponding directory, execute `./magiskboot unpack boot.img` to unpack `boot.img`, you will get a `kernel` file, this is your stock kernel.
|
||||
5. Replace `kernel` with `Image` by running the command: `mv -f Image kernel`.
|
||||
6. Execute `./magiskboot repack boot.img` to repack the boot image, and you will get a `new-boot.img` file, flash this file to device by fastboot.
|
||||
|
||||
::: info
|
||||
Official `magiskboot` can run in `Linux` environments normally, if you're a Linux user, you can use the official build.
|
||||
:::
|
||||
|
||||
## Install with custom Recovery {#install-with-custom-recovery}
|
||||
|
||||
Prerequisite: Your device must have a custom Recovery, such as TWRP. If there is no custom Recovery available for your device, use another method.
|
||||
|
||||
Steps:
|
||||
|
||||
1. On [GitHub Releases](https://github.com/tiann/KernelSU/releases), download the ZIP package starting with `AnyKernel3` that matches your device's version. For example, if the device's kernel version is `android12-5.10.66`, then you should download the `AnyKernel3-android12-5.10.66_yyyy-MM.zip` file (where `yyyy` is the year and `MM` is the month).
|
||||
2. Reboot the device into TWRP.
|
||||
3. Use ADB to place AnyKernel3-*.zip into the device's `/sdcard` location and choose to install it in the TWRP GUI, or you can directly run `adb sideload AnyKernel-*.zip` to install.
|
||||
|
||||
Note: This method is suitable for any installation (not limited to initial installation or subsequent upgrades), as long as you're using TWRP.
|
||||
|
||||
## Other methods
|
||||
|
||||
In fact, all of these installation methods have only one main idea, which is to **replace the original kernel for the one provided by KernelSU**, as long as this can be achieved, it can be installed. The following are other possible methods:
|
||||
|
||||
1. First, install Magisk, get root privileges through Magisk, and then use the Kernel Flasher to flash the AnyKernel3 ZIP from KernelSU.
|
||||
2. Use any flashing toolkit on PC to flash the kernel provided by KernelSU.
|
||||
|
||||
However, if it doesn't work, please try `magiskboot` approach.
|
||||
@@ -1,48 +0,0 @@
|
||||
# Module WebUI
|
||||
|
||||
In addition to executing boot scripts and modifying system files, KernelSU's modules also support displaying UI interfaces and interacting directly with users.
|
||||
|
||||
The module can write HTML + CSS + JavaScript pages through any web technology. KernelSU's manager will display these pages through WebView. It also provides some APIs to interact with the system, such as executing shell commands.
|
||||
|
||||
## `webroot` directory
|
||||
|
||||
Web resource files should be placed in the `webroot` subdirectory of the module root directory, and there **MUST** be a file named `index.html`, which is the module page entry. The simplest module structure containing a web interface is as follows:
|
||||
|
||||
```txt
|
||||
❯ tree .
|
||||
.
|
||||
|-- module.prop
|
||||
`-- webroot
|
||||
`-- index.html
|
||||
```
|
||||
|
||||
::: warning
|
||||
When installing the module, KernelSU will automatically set the permissions and SELinux context for this directory. If you don't know what you're doing, do not set the permissions for this directory yourself!
|
||||
:::
|
||||
|
||||
If your page contains CSS and JavaScript, you need to place it in this directory as well.
|
||||
|
||||
## JavaScript API
|
||||
|
||||
If it's just a display page, it will function like a regular web page. However, the most important thing is that KernelSU provides a series of system APIs, allowing the implementation of module-specific functions.
|
||||
|
||||
KernelSU provides a JavaScript library, which is published on [npm](https://www.npmjs.com/package/kernelsu) and can be used in the JavaScript code of your web pages.
|
||||
|
||||
For example, you can execute a shell command to obtain a specific configuration or modify a property:
|
||||
|
||||
```JavaScript
|
||||
import { exec } from 'kernelsu';
|
||||
|
||||
const { errno, stdout } = exec("getprop ro.product.model");
|
||||
```
|
||||
|
||||
For another example, you can make the web page display full screen, or display a toast.
|
||||
|
||||
[API documentation](https://www.npmjs.com/package/kernelsu)
|
||||
|
||||
If you find that the existing API doesn't meet your needs or is inconvenient to use, you're welcome to give us suggestions [here](https://github.com/tiann/KernelSU/issues)!
|
||||
|
||||
## Some tips
|
||||
|
||||
1. You can use `localStorage` as usual to store some data, but keep in mind that it will be lost if the manager app is uninstalled. If you need persistent storage, you will need to manually save the data in a specific directory.
|
||||
2. For simple pages, we recommend using [parceljs](https://parceljs.org/) for packaging. It requires no initial configuration and is extremely easy to use. However, if you're a front-end expert or have your own preferences, feel free to use the tool of your choice!
|
||||
@@ -1,326 +0,0 @@
|
||||
# Module guide
|
||||
|
||||
KernelSU provides a module mechanism that achieves the effect of modifying the system directory while maintaining the integrity of the system partition. This mechanism is commonly known as "systemless".
|
||||
|
||||
The module mechanism of KernelSU is almost the same as that of Magisk. If you're familiar with Magisk module development, developing KernelSU modules is very similar. You can skip the introduction of modules below and just read [Difference with Magisk](difference-with-magisk.md).
|
||||
|
||||
## WebUI
|
||||
|
||||
KernelSU's modules support displaying interfaces and interacting with users. For more details, refer to the [WebUI documentation](module-webui.md).
|
||||
|
||||
## BusyBox
|
||||
|
||||
KernelSU ships with a feature-complete BusyBox binary (including full SELinux support). The executable is located at `/data/adb/ksu/bin/busybox`. KernelSU's BusyBox supports runtime toggle-able "ASH Standalone Shell Mode". What this Standalone Mode means is that when running in the `ash` shell of BusyBox, every single command will directly use the applet within BusyBox, regardless of what is set as `PATH`. For example, commands like `ls`, `rm`, `chmod` will **NOT** use what is in `PATH` (in the case of Android by default it will be `/system/bin/ls`, `/system/bin/rm`, and `/system/bin/chmod` respectively), but will instead directly call internal BusyBox applets. This makes sure that scripts always run in a predictable environment and always have the full suite of commands no matter which Android version it is running on. To force a command _not_ to use BusyBox, you have to call the executable with full paths.
|
||||
|
||||
Every single shell script running in the context of KernelSU will be executed in BusyBox's `ash` shell with Standalone Mode enabled. For what is relevant to 3rd party developers, this includes all boot scripts and module installation scripts.
|
||||
|
||||
For those who want to use this Standalone Mode feature outside of KernelSU, there are 2 ways to enable it:
|
||||
|
||||
1. Set environment variable `ASH_STANDALONE` to `1` <br>Example: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Toggle with command-line options:<br>`/data/adb/ksu/bin/busybox sh -o standalone <script>`
|
||||
|
||||
To make sure all subsequent `sh` shell executed also runs in Standalone Mode, option 1 is the preferred method (and this is what KernelSU and the KernelSU manager use internally) as environment variables are inherited down to child processes.
|
||||
|
||||
::: tip DIFFERENCE WITH MAGISK
|
||||
KernelSU's BusyBox is now using the binary file compiled directly from the Magisk project. **Thanks to Magisk!** Therefore, you don't need to worry about compatibility issues between BusyBox scripts in Magisk and KernelSU, as they're exactly the same!
|
||||
:::
|
||||
|
||||
## KernelSU modules
|
||||
|
||||
A KernelSU module is a folder placed in `/data/adb/modules` with the structure below:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- The folder is named with the ID of the module
|
||||
│ │
|
||||
│ │ *** Module Identity ***
|
||||
│ │
|
||||
│ ├── module.prop <--- This file stores the metadata of the module
|
||||
│ │
|
||||
│ │ *** Main Contents ***
|
||||
│ │
|
||||
│ ├── system <--- This folder will be mounted if skip_mount does not exist
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** Status Flags ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- If exists, KernelSU will NOT mount your system folder
|
||||
│ ├── disable <--- If exists, the module will be disabled
|
||||
│ ├── remove <--- If exists, the module will be removed next reboot
|
||||
│ │
|
||||
│ │ *** Optional Files ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── post-mount.sh <--- This script will be executed in post-mount
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
│ ├── boot-completed.sh <--- This script will be executed on boot completed
|
||||
| ├── uninstall.sh <--- This script will be executed when KernelSU removes your module
|
||||
| ├── action.sh <--- This script will be executed when user click the Action button in KernelSU app
|
||||
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
|
||||
│ ├── sepolicy.rule <--- Additional custom sepolicy rules
|
||||
│ │
|
||||
│ │ *** Auto Generated, DO NOT MANUALLY CREATE OR MODIFY ***
|
||||
│ │
|
||||
│ ├── vendor <--- A symlink to $MODID/system/vendor
|
||||
│ ├── product <--- A symlink to $MODID/system/product
|
||||
│ ├── system_ext <--- A symlink to $MODID/system/system_ext
|
||||
│ │
|
||||
│ │ *** Any additional files / folders are allowed ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: tip DIFFERENCE WITH MAGISK
|
||||
KernelSU doesn't have built-in support for Zygisk, so there is no content related to Zygisk in the module. However, you can use [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) to support Zygisk modules. In this case, the content of the Zygisk module is identical to that supported by Magisk.
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
`module.prop` is a configuration file for a module. In KernelSU, if a module doesn't contain this file, it won't be recognized as a module. The format of this file is as follows:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versionCode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` has to match this regular expression: `^[a-zA-Z][a-zA-Z0-9._-]+$` .<br>
|
||||
Example: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
This is the **unique identifier** of your module. You should not change it once published.
|
||||
- `versionCode` has to be an **integer**. This is used to compare versions.
|
||||
- Others that were not mentioned above can be any **single line** string.
|
||||
- Make sure to use the `UNIX (LF)` line break type and not the `Windows (CR+LF)` or `Macintosh (CR)`.
|
||||
|
||||
### Shell scripts
|
||||
|
||||
Please read the [Boot scripts](#boot-scripts) section to understand the difference between `post-fs-data.sh` and `service.sh`. For most module developers, `service.sh` should be good enough if you just need to run a boot script, if you need to run the script after boot completed, please use `boot-completed.sh`. If you want to do something after mounting OverlayFS, please use `post-mount.sh`.
|
||||
|
||||
In all scripts of your module, please use `MODDIR=${0%/*}` to get your module's base directory path; do **NOT** hardcode your module path in scripts.
|
||||
|
||||
::: tip DIFFERENCE WITH MAGISK
|
||||
You can use the environment variable `KSU` to determine if a script is running in KernelSU or Magisk. If running in KernelSU, this value will be set to `true`.
|
||||
:::
|
||||
|
||||
### `system` directory
|
||||
|
||||
The contents of this directory will be overlaid on top of the system's `/system` partition using OverlayFS after the system is booted. This means that:
|
||||
|
||||
1. Files with the same name as those in the corresponding directory in the system will be overwritten by the files in this directory.
|
||||
2. Folders with the same name as those in the corresponding directory in the system will be merged with the folders in this directory.
|
||||
|
||||
If you want to delete a file or folder in the original system directory, you need to create a file with the same name as the file/folder in the module directory using `mknod filename c 0 0`. This way, the OverlayFS system will automatically "whiteout" this file as if it has been deleted (the /system partition isn't actually changed).
|
||||
|
||||
You can also declare a variable named `REMOVE` containing a list of directories in `customize.sh` to execute removal operations, and KernelSU will automatically execute `mknod <TARGET> c 0 0` in the corresponding directories of the module. For example:
|
||||
|
||||
```sh
|
||||
REMOVE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
The above list will execute `mknod $MODPATH/system/app/YouTube c 0 0` and `mknod $MODPATH/system/app/Bloatware c 0 0`, `/system/app/YouTube` and `/system/app/Bloatware` will be removed after the module takes effect.
|
||||
|
||||
If you want to replace a directory in the system, you need to create a directory with the same path in your module directory, and then set the attribute `setfattr -n trusted.overlay.opaque -v y <TARGET>` for this directory. This way, the OverlayFS system will automatically replace the corresponding directory in the system (without changing the /system partition).
|
||||
|
||||
You can declare a variable named `REPLACE` in your `customize.sh` file, which includes a list of directories to be replaced, and KernelSU will automatically perform the corresponding operations in your module directory. For example:
|
||||
|
||||
```sh
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
This list will automatically create the directories `$MODPATH/system/app/YouTube` and `$MODPATH/system/app/Bloatware`, and then execute `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` and `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. After the module takes effect, `/system/app/YouTube` and `/system/app/Bloatware` will be replaced with empty directories.
|
||||
|
||||
::: tip DIFFERENCE WITH MAGISK
|
||||
KernelSU's systemless mechanism is implemented through the kernel's OverlayFS, while Magisk currently uses magic mount (bind mount). These two implementation methods have significant differences, but the ultimate goal is the same: modifying /system files without physically modifying the /system partition.
|
||||
:::
|
||||
|
||||
If you're interested in OverlayFS, it's recommended to read the Linux Kernel's [documentation on OverlayFS](https://docs.kernel.org/filesystems/overlayfs.html).
|
||||
|
||||
### system.prop
|
||||
|
||||
This file follows the same format as `build.prop`. Each line comprises of `[key]=[value]`.
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
If your module requires some additional sepolicy patches, please add those rules into this file. Each line in this file will be treated as a policy statement.
|
||||
|
||||
## Module installer
|
||||
|
||||
A KernelSU module installer is a KernelSU module packaged in a ZIP file that can be flashed in the KernelSU manager. The simplest KernelSU module installer is just a KernelSU module packed as a ZIP file.
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (Optional, more details later)
|
||||
│ This script will be sourced by update-binary
|
||||
├── ...
|
||||
├── ... /* The rest of module's files */
|
||||
│
|
||||
```
|
||||
|
||||
::: warning
|
||||
KernelSU module is **NOT** compatible for installation in a custom Recovery!
|
||||
:::
|
||||
|
||||
### Customization
|
||||
|
||||
If you need to customize the module installation process, optionally you can create a script in the installer named `customize.sh`. This script will be **sourced** (not executed) by the module installer script after all files are extracted and default permissions and secontext are applied. This is very useful if your module requires additional setup based on the device ABI, or you need to set special permissions/secontext for some of your module files.
|
||||
|
||||
If you would like to fully control and customize the installation process, declare `SKIPUNZIP=1` in `customize.sh` to skip all default installation steps. By doing so, your `customize.sh` will be responsible to install everything by itself.
|
||||
|
||||
The `customize.sh` script runs in KernelSU's BusyBox `ash` shell with Standalone Mode enabled. The following variables and functions are available:
|
||||
|
||||
#### Variables
|
||||
|
||||
- `KSU` (bool): a variable to mark that the script is running in the KernelSU environment, and the value of this variable will always be true. You can use it to distinguish between KernelSU and Magisk.
|
||||
- `KSU_VER` (string): the version string of currently installed KernelSU (e.g. `v0.4.0`).
|
||||
- `KSU_VER_CODE` (int): the version code of currently installed KernelSU in userspace (e.g. `10672`).
|
||||
- `KSU_KERNEL_VER_CODE` (int): the version code of currently installed KernelSU in kernel space (e.g. `10672`).
|
||||
- `BOOTMODE` (bool): always be `true` in KernelSU.
|
||||
- `MODPATH` (path): the path where your module files should be installed.
|
||||
- `TMPDIR` (path): a place where you can temporarily store files.
|
||||
- `ZIPFILE` (path): your module's installation ZIP.
|
||||
- `ARCH` (string): the CPU architecture of the device. Value is either `arm`, `arm64`, `x86`, or `x64`.
|
||||
- `IS64BIT` (bool): `true` if `$ARCH` is either `arm64` or `x64`.
|
||||
- `API` (int): the API level (Android version) of the device (e.g., `23` for Android 6.0).
|
||||
|
||||
::: warning
|
||||
In KernelSU, `MAGISK_VER_CODE` is always `25200`, and `MAGISK_VER` is always `v25.2`. Please don't use these two variables to determine whether KernelSU is running or not.
|
||||
:::
|
||||
|
||||
#### Functions
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
print <msg> to console
|
||||
Avoid using 'echo' as it will not display in custom recovery's console
|
||||
|
||||
abort <msg>
|
||||
print error message <msg> to console and terminate the installation
|
||||
Avoid using 'exit' as it will skip the termination cleanup steps
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
if [context] is not set, the default is "u:object_r:system_file:s0"
|
||||
this function is a shorthand for the following commands:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
if [context] is not set, the default is "u:object_r:system_file:s0"
|
||||
for all files in <directory>, it will call:
|
||||
set_perm file owner group filepermission context
|
||||
for all directories in <directory> (including itself), it will call:
|
||||
set_perm dir owner group dirpermission context
|
||||
```
|
||||
|
||||
## Boot scripts
|
||||
|
||||
In KernelSU, scripts are divided into two types based on their running mode: post-fs-data mode and late_start service mode.
|
||||
|
||||
- post-fs-data mode
|
||||
- This stage is BLOCKING. The boot process is paused before execution is done or after 10 seconds.
|
||||
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
|
||||
- This stage happens before Zygote is started, which pretty much means everything in Android.
|
||||
- **WARNING:** Using `setprop` will deadlock the boot process! Please use `resetprop -n <prop_name> <prop_value>` instead.
|
||||
- **Only run scripts in this mode if necessary**.
|
||||
- late_start service mode
|
||||
- This stage is NON-BLOCKING. Your script runs in parallel with the rest of the booting process.
|
||||
- **This is the recommended stage to run most scripts**.
|
||||
|
||||
In KernelSU, startup scripts are divided into two types based on their storage location: general scripts and module scripts.
|
||||
|
||||
- General scripts
|
||||
- Placed in `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` or `/data/adb/boot-completed.d.`
|
||||
- Only executed if the script is set as executable (`chmod +x script.sh`)
|
||||
- Scripts in `post-fs-data.d` runs in post-fs-data mode, and scripts in `service.d` runs in late_start service mode.
|
||||
- Modules should **NOT** add general scripts during installation.
|
||||
- Module scripts
|
||||
- Placed in the module's own folder.
|
||||
- Only executed if the module is enabled.
|
||||
- `post-fs-data.sh` runs in post-fs-data mode, `service.sh` runs in late_start service mode, `boot-completed.sh` runs on boot completed, `post-mount.sh` runs on OverlayFS mounted.
|
||||
|
||||
All boot scripts will run in KernelSU's BusyBox `ash` shell with Standalone Mode enabled.
|
||||
|
||||
### Boot scripts process explanation
|
||||
|
||||
The following is the relevant boot process for Android (some parts are omitted), which includes the operation of KernelSU (with leading asterisks), and can help you better understand the purpose of these module scripts:
|
||||
|
||||
```txt
|
||||
0. Bootloader (nothing on screen)
|
||||
load patched boot.img
|
||||
load kernel:
|
||||
- GKI mode: GKI kernel with KernelSU integrated
|
||||
- LKM mode: stock kernel
|
||||
...
|
||||
|
||||
1. kernel exec init (OEM logo on screen):
|
||||
- GKI mode: stock init
|
||||
- LKM mode: exec ksuinit, insmod kernelsu.ko, exec stock init
|
||||
mount /dev, /dev/pts, /proc, /sys, etc.
|
||||
property-init -> read default props
|
||||
read init.rc
|
||||
...
|
||||
early-init -> init -> late_init
|
||||
early-fs
|
||||
start vold
|
||||
fs
|
||||
mount /vendor, /system, /persist, etc.
|
||||
post-fs-data
|
||||
*safe mode check
|
||||
*execute general scripts in post-fs-data.d/
|
||||
*load sepolicy.rule
|
||||
*mount tmpfs
|
||||
*execute module scripts post-fs-data.sh
|
||||
**(Zygisk)./bin/zygisk-ptrace64 monitor
|
||||
*(pre)load system.prop (same as resetprop -n)
|
||||
*remount modules /system
|
||||
*execute general scripts in post-mount.d/
|
||||
*execute module scripts post-mount.sh
|
||||
zygote-start
|
||||
load_all_props_action
|
||||
*execute resetprop (actual set props for resetprop with -n option)
|
||||
... -> boot
|
||||
class_start core
|
||||
start-service logd, console, vold, etc.
|
||||
class_start main
|
||||
start-service adb, netd (iptables), zygote, etc.
|
||||
|
||||
2. kernel2user init (ROM animation on screen, start by service bootanim)
|
||||
*execute general scripts in service.d/
|
||||
*execute module scripts service.sh
|
||||
*set props for resetprop without -p option
|
||||
**(Zygisk) hook zygote (start zygiskd)
|
||||
**(Zygisk) mount zygisksu/module.prop
|
||||
start system apps (autostart)
|
||||
...
|
||||
boot complete (broadcast ACTION_BOOT_COMPLETED event)
|
||||
*execute general scripts in boot-completed.d/
|
||||
*execute module scripts boot-completed.sh
|
||||
|
||||
3. User operable (lock screen)
|
||||
input password to decrypt /data/data
|
||||
*actual set props for resetprop with -p option
|
||||
start user apps (autostart)
|
||||
```
|
||||
|
||||
If you're interested in Android Init Language, it's recommended to read its [documentation](https://android.googlesource.com/platform/system/core/+/master/init/README.md).
|
||||
@@ -1,50 +0,0 @@
|
||||
# Rescue from bootloop
|
||||
|
||||
When updating a device, situations may arise where the device becomes "bricked". In theory, if you only use fastboot to flash the boot partition or install incompatible modules that cause the device to fail during boot, it can be restored through appropriate operations. This document aims to provide emergency methods to help you recover a "bricked" device.
|
||||
|
||||
## Brick by flashing boot partition
|
||||
|
||||
In KernelSU, the following situations may cause boot brick when flashing the boot partition:
|
||||
|
||||
1. You flashed a boot image in the wrong format. For example, if your device's boot format is `gz`, but you flashed an image in `lz4` format, the device won't boot.
|
||||
2. Your device needs to disable AVB verification to boot correctly, which usually requires wiping all data from the device.
|
||||
3. Your kernel contains bugs or isn't compatible with your device's flash.
|
||||
|
||||
No matter the situation, you can recover by **flashing the stock boot image**. Therefore, at the beginning of the installation guide, we strongly recommend that you back up your stock boot before flashing. If you didn't back it up, you can obtain the original factory boot from other users with the same device or from the official firmware.
|
||||
|
||||
## Brick by modules
|
||||
|
||||
The installation of modules can be one of the most common causes of bricking your device, but we must seriously warn you: **DO NOT INSTALL MODULES FROM UNKNOWN SOURCES!** Since modules have root privileges, they can cause irreversible damage to your device!
|
||||
|
||||
### Normal modules
|
||||
|
||||
If you have flashed a module that has been proven to be safe but causes your device to fail to boot, then this situation is easily recoverable in KernelSU without any worries. KernelSU has built-in mechanisms to rescue your device, including the following:
|
||||
|
||||
1. AB update
|
||||
2. Rescue by pressing Volume down button
|
||||
|
||||
#### AB update
|
||||
|
||||
KernelSU's module updates are based on the Android system's AB update mechanism used in OTA updates. When you install a new module or update an existing one, it won't directly modify the currently used module file. Instead, all modules are integrated into a new update image. After the system is restarted, it will attempt to boot using this new update image. If the Android system boots successfully, the modules will be effectively updated.
|
||||
|
||||
Therefore, the simplest and most commonly used method to rescue your device is to **force a reboot**. If you're unable to start your system after flashing a module, you can press and hold the power button for more than 10 seconds, and the system will automatically reboot. After rebooting, it will roll back to the state before the module update, and any previously updated modules will be automatically disabled.
|
||||
|
||||
#### Rescue by pressing Volume down button
|
||||
|
||||
If AB update hasn't yet resolved the issue, you can try using **Safe Mode**. In this mode, all modules are disabled.
|
||||
|
||||
There are two ways to enter Safe Mode:
|
||||
|
||||
1. The built-in Safe Mode of some systems: Some systems have a built-in Safe Mode that can be accessed by long-pressing the Volume down button. In other systems (such as HyperOS), Safe Mode can be activated from the Recovery. When entering the system's Safe Mode, KernelSU will also enter this mode and automatically disable the modules.
|
||||
2. The built-in Safe Mode of KernelSU: In this case, the method is to **press the Volume down key continuously more than three times** after the first boot screen.
|
||||
|
||||
After entering Safe Mode, all modules on the Module page in the KernelSU manager will be disabled. However, you can still perform the "uninstall" operation to remove any modules that may be causing issues.
|
||||
|
||||
The built-in Safe Mode is implemented in the kernel, so there is no possibility of missing important events due to interception. However, for non-GKI kernels, manual code integration may be required. For this, refer to the official documentation for guidance.
|
||||
|
||||
### Malicious modules
|
||||
|
||||
If the above methods cannot rescue your device, it's highly likely that the module you installed has malicious operations or has damaged your device in some other way. In this case, there are only two suggestions:
|
||||
|
||||
1. Wipe the data and flash the official system.
|
||||
2. Consult the after-sales service.
|
||||
@@ -1,30 +0,0 @@
|
||||
# Unofficially supported devices
|
||||
|
||||
::: warning
|
||||
In this page, there are kernels for non-GKI devices supporting KernelSU maintained by other developers.
|
||||
:::
|
||||
|
||||
::: warning
|
||||
This page is intended only to help you find the source code corresponding to your device. It **DOES NOT** mean that the source code has been reviewed by KernelSU developers. You should use it at your own risk.
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Maintainer</th>
|
||||
<th>Repository</th>
|
||||
<th>Support devices</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# What is KernelSU?
|
||||
|
||||
KernelSU is a root solution for Android GKI devices, it works in kernel mode and grants root permission to userspace apps directly in kernel space.
|
||||
|
||||
## Features
|
||||
|
||||
The main feature of KernelSU is that it's **kernel-based**. KernelSU works in kernel mode, enabling it to provide a kernel interface that we never had before. For example, it's possible to add hardware breakpoints to any process in kernel mode, access the physical memory of any process invisibly, intercept any system call (syscall) within the kernel space, among other functionalities.
|
||||
|
||||
Additionally, KernelSU provides a module system via OverlayFS, which allows you to load your custom plugin into system. It also provides a mechanism to modify files in `/system` partition.
|
||||
|
||||
## How to use KernelSU?
|
||||
|
||||
Please refer: [Installation](installation)
|
||||
|
||||
## How to build KernelSU?
|
||||
|
||||
Please refer: [How to build](how-to-build)
|
||||
|
||||
## Discussion
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,26 +0,0 @@
|
||||
# Perbedaan dengan Magisk
|
||||
|
||||
Meskipun ada banyak kesamaan antara modul KernelSU dan modul Magisk, pasti ada beberapa perbedaan karena mekanisme implementasinya yang sangat berbeda. Jika Anda ingin modul Anda berjalan di Magisk dan KernelSU, Anda harus memahami perbedaan ini.
|
||||
|
||||
## Kesamaan
|
||||
|
||||
- Format file modul: keduanya menggunakan format zip untuk mengatur modul, dan format modulnya hampir sama
|
||||
- Direktori pemasangan modul: keduanya terletak di `/data/adb/modules`
|
||||
- Tanpa sistem: keduanya mendukung modifikasi / sistem dengan cara tanpa sistem melalui modul
|
||||
- post-fs-data.sh: waktu eksekusi dan semantiknya persis sama
|
||||
- service.sh: waktu eksekusi dan semantiknya persis sama
|
||||
- system.prop: sepenuhnya sama
|
||||
- sepolicy.rule: sama persis
|
||||
- BusyBox: skrip dijalankan di BusyBox dengan "mode mandiri" diaktifkan di kedua kasus
|
||||
|
||||
## Perbedaan
|
||||
|
||||
Sebelum memahami perbedaannya, Anda perlu mengetahui cara membedakan apakah modul Anda berjalan di KernelSU atau Magisk. Anda dapat menggunakan variabel lingkungan `KSU` untuk membedakannya di semua tempat di mana Anda dapat menjalankan skrip modul (`customize.sh`, `post-fs-data.sh`, `service.sh`). Di KernelSU, variabel lingkungan ini akan disetel ke `true`.
|
||||
|
||||
Berikut beberapa perbedaannya:
|
||||
|
||||
- Modul KernelSU tidak dapat diinstal dalam mode Pemulihan.
|
||||
- Modul KernelSU tidak memiliki dukungan bawaan untuk Zygisk (tetapi Anda dapat menggunakan modul Zygisk melalui [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
- Metode untuk mengganti atau menghapus file dalam modul KernelSU sama sekali berbeda dari Magisk. KernelSU tidak mendukung metode `.replace`. Sebagai gantinya, Anda perlu membuat file dengan nama yang sama dengan `mknod filename c 0 0` untuk menghapus file terkait.
|
||||
- Direktori untuk BusyBox berbeda. BusyBox bawaan di KernelSU terletak di `/data/adb/ksu/bin/busybox`, sedangkan di Magisk terletak di `/data/adb/magisk/busybox`. **Perhatikan bahwa ini adalah perilaku internal KernelSU dan dapat berubah di masa mendatang!**
|
||||
- KernelSU tidak mendukung file `.replace`; namun, KernelSU mendukung variabel `REMOVE` dan `REPLACE` untuk menghapus atau mengganti file dan folder.
|
||||
@@ -1,48 +0,0 @@
|
||||
# FAQ
|
||||
|
||||
## Apakah KernelSU mendukung perangkat saya?
|
||||
|
||||
Pertama, perangkatmu harus bisa dibuka bootloadernya. Jika tiddak bisa, berarti tidak memungkinkan untuk bekerja.
|
||||
|
||||
Lalu instal aplikasi KernelSU manager di dalam perangkatmu dan buka, jika terlihat `Unsupported` berarti perangkatmu tidak didukung dan tidak akan didukung di kemudian hari.
|
||||
|
||||
## Apakah KernelSU membutuhkan buka-bootloader?
|
||||
|
||||
Ya, seharusnya.
|
||||
|
||||
## Apakah KernelSU mendukung modul?
|
||||
|
||||
Ya, Tetapi masih dalam versi awal, bisa jadi ngebug. Mohon tunggu sampai semuanya stabil :)
|
||||
|
||||
## Apakah KernelSU mendukung Xposed?
|
||||
|
||||
Ya, [Dreamland](https://github.com/canyie/Dreamland) dan [TaiChi](https://taichi.cool) sekarang bekerja sebagian, Dan kita sedang mencoba untuk membuat Xposed Framework lainnya bekerja.
|
||||
|
||||
## Apakah KernelSU kompatibel dengan Magisk?
|
||||
|
||||
Sistem modul KernelSU bertentangan dengan magic mount Magisk, jika ada modul yang diaktifkan di KernelSU, maka seluruh Magisk tidak akan bekerja.
|
||||
|
||||
Tetapi jika Anda hanya menggunakan `su` dari KernelSU, maka KernelSU akan bekerja dengan baik dengan Magisk: KernelSU memodifikasi `kernel` dan Magisk memodifikasi `ramdisk`, keduanya dapat bekerja bersama.
|
||||
|
||||
## Akankah KernelSU menggantikan Magisk?
|
||||
|
||||
Kami rasa tidak dan itu bukan tujuan kami. Magisk sudah cukup baik untuk solusi root userspace dan akan bertahan lama. Tujuan KernelSU adalah untuk menyediakan antarmuka kernel kepada pengguna, bukan untuk menggantikan Magisk.
|
||||
|
||||
## Dapatkah KernelSU mendukung perangkat non GKI?
|
||||
|
||||
Hal ini dimungkinkan. Tetapi Anda harus mengunduh sumber kernel dan mengintegrasikan KernelSU ke source tree dan mengkompilasi kernel sendiri.
|
||||
|
||||
## Dapatkah KernelSU mendukung perangkat di bawah Android 12?
|
||||
|
||||
Kernel perangkatlah yang mempengaruhi kompatibilitas KernelSU dan tidak ada hubungannya dengan versi Android, satu-satunya batasan adalah bahwa perangkat yang diluncurkan dengan Android 12 harus menggunakan kernel 5.10+ (perangkat GKI). Jadi:
|
||||
|
||||
1. Perangkat yang diluncurkan dengan Android 12 harus didukung.
|
||||
2. Perangkat dengan kernel lama (Beberapa perangkat Android 12 juga memiliki kernel lama) dapat dikompilasi (Anda harus membuat kernel sendiri)
|
||||
|
||||
## Dapatkah KernelSU mendukung kernel lama?
|
||||
|
||||
Ada kemungkinan, KernelSU sudah di-backport ke kernel 4.14 sekarang, untuk kernel yang lebih lama, Anda harus melakukan backport secara manual dan menyambut baik PR darimu!
|
||||
|
||||
## Cara mengintegrasikan KernelSU untuk kernel lama?
|
||||
|
||||
Silakan merujuk ke [guide](how-to-integrate-for-non-gki)
|
||||
@@ -1,63 +0,0 @@
|
||||
# Bagaimana caranya untuk build KernelSU?
|
||||
|
||||
Pertama, Anda harus membaca dokumen resmi Android untuk membangun kernel:
|
||||
|
||||
1. [Building Kernels](https://source.android.com/docs/setup/build/building-kernels)
|
||||
2. [GKI Release Builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
> Halaman ini untuk perangkat GKI, jika Anda menggunakan kernel lama, silakan lihat [cara mengintegrasikan KernelSU untuk kernel lama](how-to-integrate-for-non-gki)
|
||||
|
||||
## Build Kernel
|
||||
|
||||
### Menyinkronkan source code kernel
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
`<kernel_manifest.xml>` adalah berkas manifes yang dapat menentukan build secara unik, Anda dapat menggunakan manifes tersebut untuk melakukan build yang dapat diprediksikan ulang. Anda harus mengunduh berkas manifes dari [Google GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
### Build
|
||||
|
||||
Silakan periksa [official docs](https://source.android.com/docs/setup/build/building-kernels) terlebih dahulu.
|
||||
|
||||
Sebagai contoh, kita perlu build image kernel aarch64:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Jangan lupa untuk menambahkan flag `LTO=thin`, jika tidak, maka build akan gagal jika memori komputer Anda kurang dari 24GB.
|
||||
|
||||
Mulai dari Android 13, kernel dibuild oleh `bazel`:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
|
||||
## Build Kernel dengan KernelSU
|
||||
|
||||
Jika Anda dapat build kernel dengan sukses, maka build KernelSU sangatlah mudah, jalankan perintah ini di root dir kernel source:
|
||||
|
||||
- Latest tag(stable)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
- main branch(dev)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
- Select tag(Such as v0.5.2)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
Dan kemudian build ulang kernel dan Anda akan mendapatkan image kernel dengan KernelSU!
|
||||
@@ -1,249 +0,0 @@
|
||||
# Bagaimana Caranya untuk mengintegrasikan KernelSU ke kernel non GKI?
|
||||
|
||||
KernelSU dapat diintegrasikan ke kernel non GKI, dan saat ini sudah di-backport ke 4.14, dan juga dapat dijalankan pada kernel di bawah 4.14.
|
||||
|
||||
Karena fragmentasi kernel non GKI, kami tidak memiliki cara yang seragam untuk membangunnya, sehingga kami tidak dapat menyediakan gambar boot non GKI. Tetapi Anda dapat membangun kernel sendiri dengan KernelSU yang terintegrasi.
|
||||
|
||||
Pertama, Anda harus dapat membangun kernel yang dapat di-boot dari kode sumber kernel, jika kernel tersebut tidak open source, maka akan sulit untuk menjalankan KernelSU untuk perangkat Anda.
|
||||
|
||||
Jika Anda dapat membuat kernel yang dapat di-booting, ada dua cara untuk mengintegrasikan KernelSU ke kode sumber kernel:
|
||||
|
||||
1. Secara otomatis dengan `kprobe`
|
||||
2. Secara manual
|
||||
|
||||
## Integrasikan dengan kprobe
|
||||
|
||||
KernelSU menggunakan kprobe untuk melakukan hook kernel, jika *kprobe* berjalan dengan baik pada kernel Anda, maka disarankan untuk menggunakan cara ini.
|
||||
|
||||
Pertama, tambahkan KernelSU ke dalam berkas kernel source tree:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
:::info
|
||||
[KernelSU 1.0 dan versi yang lebih baru tidak lagi mendukung kernel non-GKI](https://github.com/tiann/KernelSU/issues/1705). Versi terakhir yang didukung adalah `v0.9.5`, pastikan untuk menggunakan versi yang benar.
|
||||
:::
|
||||
|
||||
Kemudian, Anda harus memeriksa apakah *kprobe* diaktifkan dalam konfigurasi kernel Anda, jika tidak, tambahkan konfigurasi ini ke dalamnya:
|
||||
|
||||
```
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
Dan build kernel Anda lagi, KernelSU seharusnya bekerja dengan baik.
|
||||
|
||||
Jika Anda menemukan bahwa KPROBES masih belum diaktifkan, Anda dapat mencoba mengaktifkan `CONFIG_MODULES`. (Jika masih belum berlaku, gunakan `make menuconfig` untuk mencari ketergantungan KPROBES yang lain)
|
||||
|
||||
etapi jika Anda mengalami boot loop saat mengintegrasikan KernelSU, itu mungkin *kprobe rusak di kernel Anda*, Anda harus memperbaiki bug kprobe atau menggunakan cara kedua.
|
||||
|
||||
## Memodifikasi sumber kernel secara manual
|
||||
|
||||
Jika kprobe tidak dapat bekerja pada kernel Anda (mungkin karena bug di upstream atau kernel di bawah 4.8), maka Anda dapat mencoba cara ini:
|
||||
|
||||
Pertama, tambahkan KernelSU ke dalam direktori kernel source tree:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
Kemudian, tambahkan panggilan KernelSU ke source kernel, berikut ini adalah patch yang dapat dirujuk:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Get basic and extra attributes by filename
|
||||
* @dfd: A file descriptor representing the base dir for a relative filename
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
Anda harus menemukan empat fungsi dalam kernel source:
|
||||
|
||||
1. do_faccessat, usually in `fs/open.c`
|
||||
2. do_execveat_common, usually in `fs/exec.c`
|
||||
3. vfs_read, usually in `fs/read_write.c`
|
||||
4. vfs_statx, usually in `fs/stat.c`
|
||||
|
||||
Jika kernel anda tidak memiliki `vfs_statx`, maka gunakan `vfs_fstatat` alih-alih:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fstat);
|
||||
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+
|
||||
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int flag)
|
||||
{
|
||||
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||
+
|
||||
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH)) != 0)
|
||||
goto out;
|
||||
```
|
||||
|
||||
Untuk kernel lebih awal dari 4.17, jika anda menemukan `do_faccessat`, hanya pergi ke definisi yang sama `faccessat` syscall dan tempatkan pemanggil di sini:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 2ff887661237..e758d7db7663 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return error;
|
||||
}
|
||||
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
To enable KernelSU's builtin SafeMode, You should also modify `input_handle_event` in `drivers/input/input.c`:
|
||||
|
||||
:::tip
|
||||
Fitur ini sangat direkomendasikan, serta sangat membantu untuk memulihkan pada saat bootloop!
|
||||
:::
|
||||
|
||||
```diff
|
||||
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
||||
index 45306f9ef247..815091ebfca4 100755
|
||||
--- a/drivers/input/input.c
|
||||
+++ b/drivers/input/input.c
|
||||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev,
|
||||
return disposition;
|
||||
}
|
||||
|
||||
+extern bool ksu_input_hook __read_mostly;
|
||||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);
|
||||
+
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition = input_get_disposition(dev, type, code, &value);
|
||||
+
|
||||
+ if (unlikely(ksu_input_hook))
|
||||
+ ksu_handle_input_handle_event(&type, &code, &value);
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
Terakhir, edit `KernelSU/kernel/ksu.c` dan beri komentar pada `enable_sucompat()` lalu build kernel Anda lagi, KernelSU akan bekerja dengan baik.
|
||||
@@ -1,32 +0,0 @@
|
||||
# Instalasi
|
||||
|
||||
## Periksa apakah perangkat Anda didukung
|
||||
|
||||
Unduh aplikasi manajer KernelSU dari [github releases](https://github.com/tiann/KernelSU/releases), lalu instal aplikasi ke perangkat dan buka aplikasi:
|
||||
|
||||
- Jika aplikasi menunjukkan `Unsupported`, itu berarti **Anda harus mengkompilasi kernel sendiri**, KernelSU tidak akan dan tidak pernah menyediakan boot image untuk Anda flash.
|
||||
- Jika aplikasi menunjukkan `Not installed`, maka perangkat Anda secara resmi didukung oleh KernelSU.
|
||||
|
||||
## Temukan boot.img yang tepat
|
||||
|
||||
KernelSU menyediakan boot.img umum untuk perangkat GKI, Anda harus mem-flash boot.img ke partisi boot perangkat Anda.
|
||||
|
||||
Anda dapat mengunduh boot.img dari [github actions for kernel] (https://github.com/tiann/KernelSU/actions/workflows/build-kernel.yml), perlu diketahui bahwa Anda harus menggunakan versi boot.img yang tepat. Sebagai contoh, jika perangkat Anda menunjukkan bahwa kernelnya adalah `5.10.101`, maka Anda harus mengunduh `5.10.101-xxxx.boot.xxx`.
|
||||
|
||||
Dan juga, silakan periksa format boot.img Anda, Anda harus menggunakan format yang tepat, seperti `lz4`、`gz`.
|
||||
|
||||
## Flash boot.img ke perangkat
|
||||
|
||||
Hubungkan perangkat Anda dengan `adb` lalu jalankan `adb reboot bootloader` untuk masuk ke mode fastboot, lalu gunakan perintah ini untuk mem-flash KernelSU:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
## Reboot
|
||||
|
||||
Ketika di-flash, Anda harus menyalakan ulang perangkat Anda:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
@@ -1,255 +0,0 @@
|
||||
# Panduan module
|
||||
|
||||
KernelSU menyediakan mekanisme modul yang mencapai efek memodifikasi direktori sistem dengan tetap menjaga integritas partisi sistem. Mekanisme ini umumnya dikenal sebagai "tanpa sistem".
|
||||
|
||||
Mekanisme modul KernelSU hampir sama dengan Magisk. Jika Anda terbiasa dengan pengembangan modul Magisk, mengembangkan modul KernelSU sangat mirip. Anda dapat melewati pengenalan modul di bawah ini dan hanya perlu membaca [difference-with-magisk](difference-with-magisk.md).
|
||||
|
||||
## Busybox
|
||||
|
||||
KernelSU dikirimkan dengan fitur biner BusyBox yang lengkap (termasuk dukungan penuh SELinux). Eksekusi terletak di `/data/adb/ksu/bin/busybox`. BusyBox KernelSU mendukung "Mode Shell Standalone Shell" yang dapat dialihkan waktu proses. Apa yang dimaksud dengan mode mandiri ini adalah bahwa ketika dijalankan di shell `ash` dari BusyBox, setiap perintah akan langsung menggunakan applet di dalam BusyBox, terlepas dari apa yang ditetapkan sebagai `PATH`. Misalnya, perintah seperti `ls`, `rm`, `chmod` **TIDAK** akan menggunakan apa yang ada di `PATH` (dalam kasus Android secara default akan menjadi `/system/bin/ls`, ` /system/bin/rm`, dan `/system/bin/chmod` masing-masing), tetapi akan langsung memanggil applet BusyBox internal. Ini memastikan bahwa skrip selalu berjalan di lingkungan yang dapat diprediksi dan selalu memiliki rangkaian perintah lengkap, apa pun versi Android yang menjalankannya. Untuk memaksa perintah _not_ menggunakan BusyBox, Anda harus memanggil yang dapat dieksekusi dengan path lengkap.
|
||||
|
||||
Setiap skrip shell tunggal yang berjalan dalam konteks KernelSU akan dieksekusi di shell `ash` BusyBox dengan mode mandiri diaktifkan. Untuk apa yang relevan dengan pengembang pihak ke-3, ini termasuk semua skrip boot dan skrip instalasi modul.
|
||||
|
||||
Bagi yang ingin menggunakan fitur “Standalone Mode” ini di luar KernelSU, ada 2 cara untuk mengaktifkannya:
|
||||
|
||||
1. Tetapkan variabel lingkungan `ASH_STANDALONE` ke `1`<br>Contoh: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Beralih dengan opsi baris perintah:<br>`/data/adb/ksu/bin/busybox sh -o mandiri <script>`
|
||||
|
||||
Untuk memastikan semua shell `sh` selanjutnya dijalankan juga dalam mode mandiri, opsi 1 adalah metode yang lebih disukai (dan inilah yang digunakan secara internal oleh KernelSU dan manajer KernelSU) karena variabel lingkungan diwariskan ke proses anak.
|
||||
|
||||
::: perbedaan tip dengan Magisk
|
||||
|
||||
BusyBox KernelSU sekarang menggunakan file biner yang dikompilasi langsung dari proyek Magisk. **Berkat Magisk!** Oleh karena itu, Anda tidak perlu khawatir tentang masalah kompatibilitas antara skrip BusyBox di Magisk dan KernelSU karena keduanya persis sama!
|
||||
:::
|
||||
|
||||
## KernelSU module
|
||||
|
||||
Modul KernelSU adalah folder yang ditempatkan di `/data/adb/modules` dengan struktur di bawah ini:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- The folder is named with the ID of the module
|
||||
│ │
|
||||
│ │ *** Module Identity ***
|
||||
│ │
|
||||
│ ├── module.prop <--- This file stores the metadata of the module
|
||||
│ │
|
||||
│ │ *** Main Contents ***
|
||||
│ │
|
||||
│ ├── system <--- This folder will be mounted if skip_mount does not exist
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** Status Flags ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- If exists, KernelSU will NOT mount your system folder
|
||||
│ ├── disable <--- If exists, the module will be disabled
|
||||
│ ├── remove <--- If exists, the module will be removed next reboot
|
||||
│ │
|
||||
│ │ *** Optional Files ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
| ├── uninstall.sh <--- This script will be executed when KernelSU removes your module
|
||||
│ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop
|
||||
│ ├── sepolicy.rule <--- Additional custom sepolicy rules
|
||||
│ │
|
||||
│ │ *** Auto Generated, DO NOT MANUALLY CREATE OR MODIFY ***
|
||||
│ │
|
||||
│ ├── vendor <--- A symlink to $MODID/system/vendor
|
||||
│ ├── product <--- A symlink to $MODID/system/product
|
||||
│ ├── system_ext <--- A symlink to $MODID/system/system_ext
|
||||
│ │
|
||||
│ │ *** Any additional files / folders are allowed ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: perbedaan tip dengan Magisk
|
||||
KernelSU tidak memiliki dukungan bawaan untuk Zygisk, jadi tidak ada konten terkait Zygisk dalam modul. Namun, Anda dapat menggunakan [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) untuk mendukung modul Zygisk. Dalam hal ini, konten modul Zygisk identik dengan yang didukung oleh Magisk.
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
module.prop adalah file konfigurasi untuk sebuah modul. Di KernelSU, jika modul tidak berisi file ini, maka tidak akan dikenali sebagai modul. Format file ini adalah sebagai berikut:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versioncode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` harus cocok dengan ekspresi reguler ini: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
contoh: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
Ini adalah **pengidentifikasi unik** modul Anda. Anda tidak boleh mengubahnya setelah dipublikasikan.
|
||||
- `versionCode` harus berupa **integer**. Ini digunakan untuk membandingkan versi
|
||||
- Lainnya yang tidak disebutkan di atas dapat berupa string **satu baris**.
|
||||
- Pastikan untuk menggunakan tipe jeda baris `UNIX (LF)` dan bukan `Windows (CR+LF)` atau `Macintosh (CR)`.
|
||||
|
||||
### Shell skrip
|
||||
|
||||
Harap baca bagian [Boot Scripts](#boot-scripts) untuk memahami perbedaan antara `post-fs-data.sh` dan `service.sh`. Untuk sebagian besar pengembang modul, `service.sh` sudah cukup baik jika Anda hanya perlu menjalankan skrip boot.
|
||||
|
||||
Di semua skrip modul Anda, harap gunakan `MODDIR=${0%/*}` untuk mendapatkan jalur direktori dasar modul Anda; lakukan **TIDAK** hardcode jalur modul Anda dalam skrip.
|
||||
|
||||
::: perbedaan tip dengan Magisk
|
||||
Anda dapat menggunakan variabel lingkungan KSU untuk menentukan apakah skrip berjalan di KernelSU atau Magisk. Jika berjalan di KernelSU, nilai ini akan disetel ke true.
|
||||
:::
|
||||
|
||||
### `system` directory
|
||||
|
||||
Isi direktori ini akan dihamparkan di atas partisi sistem /sistem menggunakan overlayfs setelah sistem di-boot. Ini berarti bahwa:
|
||||
|
||||
1. File dengan nama yang sama dengan yang ada di direktori terkait di sistem akan ditimpa oleh file di direktori ini.
|
||||
2. Folder dengan nama yang sama dengan yang ada di direktori terkait di sistem akan digabungkan dengan folder di direktori ini.
|
||||
|
||||
Jika Anda ingin menghapus file atau folder di direktori sistem asli, Anda perlu membuat file dengan nama yang sama dengan file/folder di direktori modul menggunakan `mknod filename c 0 0`. Dengan cara ini, sistem overlayfs akan secara otomatis "memutihkan" file ini seolah-olah telah dihapus (partisi / sistem sebenarnya tidak diubah).
|
||||
|
||||
Anda juga dapat mendeklarasikan variabel bernama `REMOVE` yang berisi daftar direktori di `customize.sh` untuk menjalankan operasi penghapusan, dan KernelSU akan secara otomatis mengeksekusi `mknod <TARGET> c 0 0` di direktori modul yang sesuai. Misalnya:
|
||||
|
||||
``` sh
|
||||
HAPUS = "
|
||||
/sistem/aplikasi/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
Daftar di atas akan mengeksekusi `mknod $MODPATH/system/app/YouTuBe c 0 0` dan `mknod $MODPATH/system/app/Bloatware c 0 0`; dan `/system/app/YouTube` dan `/system/app/Bloatware` akan dihapus setelah modul berlaku.
|
||||
|
||||
Jika Anda ingin mengganti direktori di sistem, Anda perlu membuat direktori dengan jalur yang sama di direktori modul Anda, lalu atur atribut `setfattr -n trusted.overlay.opaque -v y <TARGET>` untuk direktori ini. Dengan cara ini, sistem overlayfs akan secara otomatis mengganti direktori terkait di sistem (tanpa mengubah partisi /sistem).
|
||||
|
||||
Anda dapat mendeklarasikan variabel bernama `REPLACE` di file `customize.sh` Anda, yang menyertakan daftar direktori yang akan diganti, dan KernelSU akan secara otomatis melakukan operasi yang sesuai di direktori modul Anda. Misalnya:
|
||||
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
|
||||
Daftar ini akan secara otomatis membuat direktori `$MODPATH/system/app/YouTube` dan `$MODPATH/system/app/Bloatware`, lalu jalankan `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/ YouTube` dan `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. Setelah modul berlaku, `/system/app/YouTube` dan `/system/app/Bloatware` akan diganti dengan direktori kosong.
|
||||
|
||||
::: perbedaan tip dengan Magisk
|
||||
|
||||
Mekanisme tanpa sistem KernelSU diimplementasikan melalui overlay kernel, sementara Magisk saat ini menggunakan magic mount (bind mount). Kedua metode implementasi tersebut memiliki perbedaan yang signifikan, tetapi tujuan utamanya sama: untuk memodifikasi file / sistem tanpa memodifikasi partisi / sistem secara fisik.
|
||||
:::
|
||||
|
||||
Jika Anda tertarik dengan overlayfs, disarankan untuk membaca [dokumentasi overlayfs](https://docs.kernel.org/filesystems/overlayfs.html) Kernel Linux.
|
||||
|
||||
### system.prop
|
||||
|
||||
File ini mengikuti format yang sama dengan `build.prop`. Setiap baris terdiri dari `[kunci]=[nilai]`.
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
Jika modul Anda memerlukan beberapa tambalan sepolicy tambahan, harap tambahkan aturan tersebut ke dalam file ini. Setiap baris dalam file ini akan diperlakukan sebagai pernyataan kebijakan.
|
||||
|
||||
## Pemasangan module
|
||||
|
||||
Penginstal modul KernelSU adalah modul KernelSU yang dikemas dalam file zip yang dapat di-flash di aplikasi pengelola KernelSU. Pemasang modul KernelSU yang paling sederhana hanyalah modul KernelSU yang dikemas sebagai file zip.
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (Optional, more details later)
|
||||
│ This script will be sourced by update-binary
|
||||
├── ...
|
||||
├── ... /* The rest of module's files */
|
||||
│
|
||||
```
|
||||
|
||||
:::peringatan
|
||||
Modul KernelSU TIDAK didukung untuk diinstal dalam pemulihan kustom!!
|
||||
:::
|
||||
|
||||
### Kostumisasi
|
||||
|
||||
Jika Anda perlu menyesuaikan proses penginstalan modul, secara opsional Anda dapat membuat skrip di penginstal bernama `customize.sh`. Skrip ini akan _sourced_ (tidak dijalankan!) oleh skrip penginstal modul setelah semua file diekstrak dan izin default serta konteks sekon diterapkan. Ini sangat berguna jika modul Anda memerlukan penyiapan tambahan berdasarkan ABI perangkat, atau Anda perlu menyetel izin khusus/konteks kedua untuk beberapa file modul Anda.
|
||||
|
||||
Jika Anda ingin sepenuhnya mengontrol dan menyesuaikan proses penginstalan, nyatakan `SKIPUNZIP=1` di `customize.sh` untuk melewati semua langkah penginstalan default. Dengan melakukannya, `customize.sh` Anda akan bertanggung jawab untuk menginstal semuanya dengan sendirinya.
|
||||
|
||||
Skrip `customize.sh` berjalan di shell BusyBox `ash` KernelSU dengan "Mode Mandiri" diaktifkan. Variabel dan fungsi berikut tersedia:
|
||||
|
||||
#### Variable
|
||||
|
||||
- `KSU` (bool): variabel untuk menandai bahwa skrip berjalan di lingkungan KernelSU, dan nilai variabel ini akan selalu benar. Anda dapat menggunakannya untuk membedakan antara KernelSU dan Magisk.
|
||||
- `KSU_VER` (string): string versi dari KernelSU yang diinstal saat ini (mis. `v0.4.0`)
|
||||
- `KSU_VER_CODE` (int): kode versi KernelSU yang terpasang saat ini di ruang pengguna (mis. `10672`)
|
||||
- `KSU_KERNEL_VER_CODE` (int): kode versi KernelSU yang terpasang saat ini di ruang kernel (mis. `10672`)
|
||||
- `BOOTMODE` (bool): selalu `true` di KernelSU
|
||||
- `MODPATH` (jalur): jalur tempat file modul Anda harus diinstal
|
||||
- `TMPDIR` (jalur): tempat di mana Anda dapat menyimpan file untuk sementara
|
||||
- `ZIPFILE` (jalur): zip instalasi modul Anda
|
||||
- `ARCH` (string): arsitektur CPU perangkat. Nilainya adalah `arm`, `arm64`, `x86`, atau `x64`
|
||||
- `IS64BIT` (bool): `true` jika `$ARCH` adalah `arm64` atau `x64`
|
||||
- `API` (int): level API (versi Android) perangkat (mis. `23` untuk Android 6.0)
|
||||
|
||||
::: peringatan
|
||||
Di KernelSU, MAGISK_VER_CODE selalu 25200 dan MAGISK_VER selalu v25.2. Tolong jangan gunakan kedua variabel ini untuk menentukan apakah itu berjalan di KernelSU atau tidak.
|
||||
:::
|
||||
|
||||
#### Fungsi
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
print <msg> to console
|
||||
Avoid using 'echo' as it will not display in custom recovery's console
|
||||
|
||||
abort <msg>
|
||||
print error message <msg> to console and terminate the installation
|
||||
Avoid using 'exit' as it will skip the termination cleanup steps
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
if [context] is not set, the default is "u:object_r:system_file:s0"
|
||||
this function is a shorthand for the following commands:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
if [context] is not set, the default is "u:object_r:system_file:s0"
|
||||
for all files in <directory>, it will call:
|
||||
set_perm file owner group filepermission context
|
||||
for all directories in <directory> (including itself), it will call:
|
||||
set_perm dir owner group dirpermission context
|
||||
```
|
||||
|
||||
## Boot scripts
|
||||
|
||||
Di KernelSU, skrip dibagi menjadi dua jenis berdasarkan mode operasinya: mode post-fs-data dan mode layanan late_start:
|
||||
|
||||
- mode pasca-fs-data
|
||||
- Tahap ini adalah BLOKIR. Proses boot dijeda sebelum eksekusi selesai, atau 10 detik telah berlalu.
|
||||
- Skrip dijalankan sebelum modul apa pun dipasang. Ini memungkinkan pengembang modul untuk menyesuaikan modul mereka secara dinamis sebelum dipasang.
|
||||
- Tahap ini terjadi sebelum Zygote dimulai, yang berarti segalanya di Android
|
||||
- **PERINGATAN:** menggunakan `setprop` akan menghentikan proses booting! Silakan gunakan `resetprop -n <prop_name> <prop_value>` sebagai gantinya.
|
||||
- **Hanya jalankan skrip dalam mode ini jika perlu.**
|
||||
- mode layanan late_start
|
||||
- Tahap ini NON-BLOCKING. Skrip Anda berjalan paralel dengan proses booting lainnya.
|
||||
- **Ini adalah tahap yang disarankan untuk menjalankan sebagian besar skrip.**
|
||||
|
||||
Di KernelSU, skrip startup dibagi menjadi dua jenis berdasarkan lokasi penyimpanannya: skrip umum dan skrip modul:
|
||||
|
||||
- Skrip Umum
|
||||
- Ditempatkan di `/data/adb/post-fs-data.d` atau `/data/adb/service.d`
|
||||
- Hanya dieksekusi jika skrip disetel sebagai dapat dieksekusi (`chmod +x script.sh`)
|
||||
- Skrip di `post-fs-data.d` berjalan dalam mode post-fs-data, dan skrip di `service.d` berjalan di mode layanan late_start.
|
||||
- Modul seharusnya **TIDAK** menambahkan skrip umum selama instalasi
|
||||
- Skrip Modul
|
||||
- Ditempatkan di folder modul itu sendiri
|
||||
- Hanya dijalankan jika modul diaktifkan
|
||||
- `post-fs-data.sh` berjalan dalam mode post-fs-data, dan `service.sh` berjalan dalam mode layanan late_start.
|
||||
|
||||
Semua skrip boot akan berjalan di shell BusyBox `ash` KernelSU dengan "Mode Mandiri" diaktifkan.
|
||||
@@ -1,50 +0,0 @@
|
||||
# Recovery dari bootloop
|
||||
|
||||
Saat mem-flash perangkat, kami mungkin menghadapi situasi di mana perangkat menjadi "bata". Secara teori, jika Anda hanya menggunakan fastboot untuk mem-flash partisi boot atau menginstal modul yang tidak sesuai yang menyebabkan perangkat gagal melakukan booting, ini dapat dipulihkan dengan operasi yang sesuai. Dokumen ini bertujuan untuk memberikan beberapa metode darurat untuk membantu Anda pulih dari perangkat "bricked".
|
||||
|
||||
## Brick saat memflash partisi boot
|
||||
|
||||
Di KernelSU, situasi berikut dapat menyebabkan bata boot saat mem-flash partisi boot:
|
||||
|
||||
1. Anda mem-flash image boot dalam format yang salah. Misalnya, jika format booting ponsel Anda adalah `gz`, tetapi Anda mem-flash image berformat `lz4`, maka ponsel tidak akan dapat melakukan booting.
|
||||
2. Ponsel Anda perlu menonaktifkan verifikasi AVB agar dapat boot dengan benar (biasanya perlu menghapus semua data di ponsel).
|
||||
3. Kernel Anda memiliki beberapa bug atau tidak cocok untuk flash ponsel Anda.
|
||||
|
||||
Apa pun situasinya, Anda dapat memulihkannya dengan **mem-flash gambar boot stok**. Oleh karena itu, di awal tutorial instalasi, kami sangat menyarankan Anda untuk mem-backup stock boot Anda sebelum melakukan flashing. Jika Anda belum mencadangkan, Anda dapat memperoleh boot pabrik asli dari pengguna lain dengan perangkat yang sama dengan Anda atau dari firmware resmi.
|
||||
|
||||
## Brick disebabkan modul
|
||||
|
||||
Memasang modul dapat menjadi penyebab yang lebih umum dari bricking perangkat Anda, tetapi kami harus memperingatkan Anda dengan serius: **Jangan memasang modul dari sumber yang tidak dikenal**! Karena modul memiliki hak akses root, mereka berpotensi menyebabkan kerusakan permanen pada perangkat Anda!
|
||||
|
||||
### Module normal
|
||||
|
||||
Jika Anda telah mem-flash modul yang telah terbukti aman tetapi menyebabkan perangkat Anda gagal booting, maka situasi ini dapat dipulihkan dengan mudah di KernelSU tanpa rasa khawatir. KernelSU memiliki mekanisme bawaan untuk menyelamatkan perangkat Anda, termasuk yang berikut:
|
||||
|
||||
1. Pembaruan AB
|
||||
2. Selamatkan dengan menekan Volume Turun
|
||||
|
||||
#### Pembaruan AB
|
||||
|
||||
Pembaruan modul KernelSU menarik inspirasi dari mekanisme pembaruan AB sistem Android yang digunakan dalam pembaruan OTA. Jika Anda menginstal modul baru atau memperbarui modul yang sudah ada, itu tidak akan langsung mengubah file modul yang sedang digunakan. Sebagai gantinya, semua modul akan dibangun ke gambar pembaruan lainnya. Setelah sistem dimulai ulang, sistem akan mencoba untuk mulai menggunakan gambar pembaruan ini. Jika sistem Android berhasil melakukan booting, modul akan benar-benar diperbarui.
|
||||
|
||||
Oleh karena itu, metode paling sederhana dan paling umum digunakan untuk menyelamatkan perangkat Anda adalah dengan **memaksa reboot**. Jika Anda tidak dapat memulai sistem Anda setelah mem-flash modul, Anda dapat menekan dan menahan tombol daya selama lebih dari 10 detik, dan sistem akan melakukan reboot secara otomatis; setelah mem-boot ulang, itu akan kembali ke keadaan sebelum memperbarui modul, dan modul yang diperbarui sebelumnya akan dinonaktifkan secara otomatis.
|
||||
|
||||
#### Recovery dengan menekan Volume Bawah
|
||||
|
||||
Jika pembaruan AB masih tidak dapat menyelesaikan masalah, Anda dapat mencoba menggunakan **Safe Mode**. Dalam Safe Mode, semua modul dinonaktifkan.
|
||||
|
||||
Ada dua cara untuk masuk ke Safe Mode:
|
||||
|
||||
1. Mode Aman bawaan dari beberapa sistem; beberapa sistem memiliki Safe Mode bawaan yang dapat diakses dengan menekan lama tombol volume turun, sementara yang lain (seperti MIUI) dapat mengaktifkan Safe Mode di Recovery. Saat memasuki Safe Mode sistem, KernelSU juga akan masuk ke Safe Mode dan secara otomatis menonaktifkan modul.
|
||||
2. Safe Mode bawaan dari KernelSU; metode pengoperasiannya adalah **tekan tombol volume turun secara terus-menerus selama lebih dari tiga kali** setelah layar boot pertama. Perhatikan bahwa ini adalah rilis pers, rilis pers, rilis pers, bukan tekan dan tahan.
|
||||
|
||||
Setelah memasuki mode aman, semua modul pada halaman modul KernelSU Manager dinonaktifkan, tetapi Anda dapat melakukan operasi "uninstall" untuk menghapus semua modul yang mungkin menyebabkan masalah.
|
||||
|
||||
Mode aman bawaan diimplementasikan di kernel, jadi tidak ada kemungkinan peristiwa penting yang hilang karena intersepsi. Namun, untuk kernel non-GKI, integrasi kode secara manual mungkin diperlukan, dan Anda dapat merujuk ke dokumentasi resmi untuk mendapatkan panduan.
|
||||
|
||||
### Module berbahaya
|
||||
|
||||
Jika metode di atas tidak dapat menyelamatkan perangkat Anda, kemungkinan besar modul yang Anda instal memiliki operasi jahat atau telah merusak perangkat Anda melalui cara lain. Dalam hal ini, hanya ada dua saran:
|
||||
|
||||
1. Hapus data dan flash sistem resmi.
|
||||
2. Konsultasikan layanan purna jual.
|
||||
@@ -1,34 +0,0 @@
|
||||
# Perangkat Yang Didukung Tidak Resmi
|
||||
|
||||
:::peringatan
|
||||
|
||||
di halaman ini, terdapat kernel untuk perangkat non-GKI yang mendukung KernelSU yang dikelola oleh pengembang lain.
|
||||
|
||||
:::
|
||||
|
||||
:::peringatan
|
||||
|
||||
Halaman ini hanya untuk Anda yang ingin menemukan kode sumber yang sesuai dengan perangkat Anda, itu **BUKAN** berarti kode sumber telah ditinjau oleh _KernelSU Developers_. Anda harus menggunakannya dengan risiko Anda sendiri.
|
||||
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pengelola</th>
|
||||
<th>Repository</th>
|
||||
<th>Perangkat yang didukung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# Apa itu KernelSU?
|
||||
|
||||
KernelSU adalah solusi root untuk perangkat GKI Android, ia bekerja dalam mode kernel dan memberikan izin root ke aplikasi userspace secara langsung di ruang kernel.
|
||||
|
||||
## Fitur
|
||||
|
||||
Fitur utama dari KernelSU adalah **berbasis kernel**. KernelSU bekerja dalam mode kernel, sehingga dapat menyediakan antarmuka kernel yang belum pernah kita miliki sebelumnya. Sebagai contoh, kita dapat menambahkan breakpoint perangkat keras ke proses apa pun dalam mode kernel; Kita dapat mengakses memori fisik dari proses apa pun tanpa diketahui oleh siapa pun; Kita dapat mencegat syscall apa pun di ruang kernel; dll.
|
||||
|
||||
Dan juga, KernelSU menyediakan sistem modul melalui overlayfs, yang memungkinkan Anda untuk memuat plugin kustom Anda ke dalam sistem. KernelSU juga menyediakan mekanisme untuk memodifikasi berkas-berkas pada partisi `/system`.
|
||||
|
||||
## Bagaimana cara menggunakannya
|
||||
|
||||
Silakan merujuk ke: [Installation](installation)
|
||||
|
||||
## Bagaimana cara men-buildnya
|
||||
|
||||
[How to build](how-to-build)
|
||||
|
||||
## Diskusi
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Sebuah solusi root kernel-based untuk Android
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: Sebuah solusi root kernel-based untuk Android
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Permulaan
|
||||
link: /id_ID/guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: Lihat di GitHub
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: Kernel-based
|
||||
details: KernelSU bekerja dalam mode Linux kernel, dan mempunyai kelebihan diatas aplikasi userspace.
|
||||
- title: Kontrol akses daftar putih
|
||||
details: Hanya aplikasi yang diberikan izin root yang bisa mengakses `su`, aplikasi lain tidak bisa mengakses su.
|
||||
- title: Dukungan modul
|
||||
details: KernelSU mendukung modifikasi /system tanpa-sistem dalam overlayfs, bahkan bisa membuat system dapat ditulis.
|
||||
- title: Sumber terbuka
|
||||
details: KernelSU adalah projek sumber terbuka dibawah lisensi GPL-3.
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Home
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: A kernel-based root solution for Android
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get started
|
||||
link: /guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: View on GitHub
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: Kernel-based
|
||||
details: As the name suggests, KernelSU works under the Linux kernel giving it more control over userspace apps.
|
||||
- title: Root access control
|
||||
details: Only permitted apps may access or see su, all other apps aren't aware of this.
|
||||
- title: Customizable root privileges
|
||||
details: KernelSU allows customization of su's uid, gid, groups, capabilities, and SELinux rules, locking up root privileges.
|
||||
- title: Modules
|
||||
details: Modules may modify /system systemlessly using OverlayFS providing significant flexibility.
|
||||
@@ -1,26 +0,0 @@
|
||||
# Magisk との違い
|
||||
|
||||
KernelSU モジュールと Magisk モジュールには多くの共通点がありますが、実装の仕組みが全く異なるため、必然的にいくつかの相違点が存在します。Magisk と KernelSU の両方でモジュールを動作させたい場合、これらの違いを理解する必要があります。
|
||||
|
||||
## 似ているところ
|
||||
|
||||
- モジュールファイルの形式:どちらもzip形式でモジュールを整理しており、モジュールの形式はほぼ同じです。
|
||||
- モジュールのインストールディレクトリ:どちらも `/data/adb/modules` に配置されます。
|
||||
- システムレス:どちらもモジュールによるシステムレスな方法で /system を変更できます。
|
||||
- post-fs-data.sh: 実行時間と意味は全く同じです。
|
||||
- service.sh: 実行時間と意味は全く同じです。
|
||||
- system.prop:全く同じです。
|
||||
- sepolicy.rule:全く同じです。
|
||||
- BusyBox:スクリプトは BusyBox で実行され、どちらの場合も「スタンドアロンモード」が有効です。
|
||||
|
||||
## 違うところ
|
||||
|
||||
違いを理解する前に、モジュールが KernelSU で動作しているか Magisk で動作しているかを区別する方法を知っておく必要があります。環境変数 `KSU` を使うとモジュールスクリプトを実行できるすべての場所 (`customize.sh`, `post-fs-data.sh`, `service.sh`) で区別できます。KernelSU では、この環境変数に `true` が設定されます。
|
||||
|
||||
以下は違いです:
|
||||
|
||||
- KernelSU モジュールは、リカバリーモードではインストールできません。
|
||||
- KernelSU モジュールには Zygisk のサポートが組み込まれていません(ただし[ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext)を使うと Zygisk モジュールを使用できます)。
|
||||
- KernelSU モジュールにおけるファイルの置換や削除の方法は、Magisk とは全く異なります。KernelSU は `.replace` メソッドをサポートしていません。その代わり、`mknod filename c 0 0` で同名のファイルを作成し、対応するファイルを削除する必要があります。
|
||||
- BusyBox 用のディレクトリが違います。KernelSU の組み込み BusyBox は `/data/adb/ksu/bin/busybox` に、Magisk では `/data/adb/magisk/busybox` に配置されます。**これは KernelSU の内部動作であり、将来的に変更される可能性があることに注意してください!**
|
||||
- KernelSU は `.replace` ファイルをサポートしていません。しかし、KernelSU はファイルやフォルダを削除したり置き換えたりするための `REMOVE` と `REPLACE` 変数をサポートしています。
|
||||
@@ -1,67 +0,0 @@
|
||||
# よくある質問
|
||||
|
||||
## 私のデバイスは KernelSU に対応していますか?
|
||||
|
||||
まず、お使いのデバイスがブートローダーのロックを解除できる必要があります。もしできないのであれば、サポート外です。
|
||||
|
||||
もし KernelSU アプリで「非対応」と表示されたら、そのデバイスは最初からサポートされていないことになりますが、カーネルソースをビルドして KernelSU を組み込むか、[非公式の対応デバイス](unofficially-support-devices)で動作させることが可能です。
|
||||
|
||||
## KernelSU を使うにはブートローダーのロックを解除する必要がありますか?
|
||||
|
||||
はい。
|
||||
|
||||
## KernelSU はモジュールに対応していますか?
|
||||
|
||||
はい。ただし初期バージョンであるためバグがある可能性があります。安定するのをお待ちください。
|
||||
|
||||
## KernelSU は Xposed に対応していますか?
|
||||
|
||||
はい。[Dreamland](https://github.com/canyie/Dreamland) や [TaiChi](https://taichi.cool) が動作します。LSPosed については、[ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) を使うと動作するようにできます。
|
||||
|
||||
## KernelSU は Zygisk に対応していますか?
|
||||
|
||||
KernelSU は Zygisk サポートを内蔵していません。[ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) を使ってください。
|
||||
|
||||
## KernelSU は Magisk と互換性がありますか?
|
||||
|
||||
KernelSU のモジュールシステムは Magisk のマジックマウントと競合しており、KernelSU で有効になっているモジュールがある場合、Magisk 全体が動作しなくなります。
|
||||
|
||||
しかし、KernelSU の `su` だけを使うのであれば、Magisk とうまく連携することができます。KernelSU は `kernel` を、Magisk は `ramdisk` を修正するため、両者は共存できます。
|
||||
|
||||
## KernelSU は Magisk の代わりになりますか?
|
||||
|
||||
私たちはそうは思っていませんし、それが目標でもありません。Magisk はユーザ空間の root ソリューションとして十分であり、長く使われ続けるでしょう。KernelSU の目標は、ユーザーにカーネルインターフェースを提供することであり、Magisk の代用ではありません。
|
||||
|
||||
## KernelSU は GKI 以外のデバイスに対応できますか?
|
||||
|
||||
可能です。ただしカーネルソースをダウンロードし、KernelSU をソースツリーに統合して、自分でカーネルをビルドする必要があります。
|
||||
|
||||
## KernelSU は Android 12 以下のデバイスに対応できますか?
|
||||
|
||||
KernelSU の互換性に影響を与えるのはデバイスのカーネルであり、Android のバージョンとは無関係です。唯一の制限は、Android 12 で発売されたデバイスはカーネル5.10以上(GKI デバイス)でなければならないことです:
|
||||
|
||||
1. Android 12 をプリインストールして発売された端末は対応しているはずです。
|
||||
2. カーネルが古い端末(一部の Android 12 端末はカーネルも古い)は対応可能ですが、カーネルは自分でビルドする必要があります。
|
||||
|
||||
## KernelSU は古いカーネルに対応できますか?
|
||||
|
||||
KernelSU は現在カーネル4.14にバックポートされていますが、それ以前のカーネルについては手動でバックポートする必要があります。プルリクエスト歓迎です!
|
||||
|
||||
## 古いカーネルに KernelSU を組み込むには?
|
||||
|
||||
[ガイド](../../guide/how-to-integrate-for-non-gki) を参考にしてください。
|
||||
|
||||
## Android のバージョンが13なのに、カーネルは「android12-5.10」と表示されるのはなぜ?
|
||||
|
||||
カーネルのバージョンは Android のバージョンと関係ありません。カーネルを書き込む必要がある場合は、常にカーネルのバージョンを使用してください。Android のバージョンはそれほど重要ではありません。
|
||||
|
||||
## KernelSU に-mount-master/global のマウント名前空間はありますか?
|
||||
|
||||
今はまだありませんが(将来的にはあるかもしれません)、グローバルマウントの名前空間に手動で切り替える方法は、以下のようにたくさんあります:
|
||||
|
||||
1. `nsenter -t 1 -m sh` でシェルをグローバル名前空間にします。
|
||||
2. `nsenter --mount=/proc/1/ns/mnt` を実行したいコマンドに追加すればグローバル名前空間で実行されます。 KernelSU は [このような使い方](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/shirkneko/zako/mksu/ui/util/KsuCli.kt#L115) もできます。
|
||||
|
||||
## GKI 1.0 なのですが、使えますか?
|
||||
|
||||
GKI1 は GKI2 と全く異なるため、カーネルは自分でビルドする必要があります。
|
||||
@@ -1,7 +0,0 @@
|
||||
# 隠し機能
|
||||
|
||||
## .ksurc
|
||||
|
||||
デフォルトでは `/system/bin/sh` は `/system/etc/mkshrc` を読み込みます。
|
||||
|
||||
`/data/adb/ksu/.ksurc` ファイルを作成することで、カスタマイズした rc ファイルを su に読み込ませられます。
|
||||
@@ -1,58 +0,0 @@
|
||||
# KernelSU のビルド方法は?
|
||||
|
||||
まず、Android の公式ドキュメントを読むべきです:
|
||||
|
||||
1. [カーネルをビルドする](https://source.android.com/docs/setup/build/building-kernels)
|
||||
2. [GKI リリースビルド](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
::: 警告
|
||||
このページは GKI デバイス用です。もし古いカーネルを使用している場合は、[古いカーネルへの KernelSU の統合方法](how-to-integrate-for-non-gki)を参照してください。
|
||||
:::
|
||||
|
||||
## カーネルビルド
|
||||
|
||||
### カーネルソースコードの同期
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
`<kernel_manifest.xml>` は、ビルドを一意に決定するマニフェストファイルです。マニフェストを使用して再現可能なビルドを行えます。マニフェストファイルは [Google GKI リリースビルド](https://source.android.com/docs/core/architecture/kernel/gki-release-builds) からダウンロードしてください。
|
||||
|
||||
### ビルド
|
||||
|
||||
まずは [公式ドキュメント](https://source.android.com/docs/setup/build/building-kernels)を確認してください。
|
||||
|
||||
たとえば、aarch64 カーネルイメージをビルドする必要があります:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
`LTO=thin` フラグを追加するのを忘れないでください。それをしないと、コンピュータのメモリが 24Gb 未満の場合にビルドに失敗する可能性があります。
|
||||
|
||||
Android 13 からは、カーネルは `bazel` によってビルドされます:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
## KernelSU を使ったカーネルビルド
|
||||
|
||||
もしカーネルを正常にビルドできた場合、KernelSU をビルドするのは簡単です。カーネルソースのルートディレクトリで任意のものを選択して実行します:
|
||||
|
||||
::: code-group
|
||||
```sh[最新タグ(安定版)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
```sh[ main ブランチ (開発用)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
```sh[タグを選択 (例:v0.5.2)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
その後でカーネルを再ビルドすると、KernelSU が組み込まれたカーネルイメージが得られます!
|
||||
@@ -1,303 +0,0 @@
|
||||
# 非 GKI カーネルで KernelSU を統合する方法は?
|
||||
|
||||
KernelSU は非 GKI カーネルに統合することが可能であり、4.14 以下のバージョンにバックポートされました。
|
||||
|
||||
非 GKI カーネルの断片化のため、統一されたビルド方法がありませんので、非 GKI ブートイメージを提供することができません。しかし、KernelSU を統合して自分自身でカーネルをビルドすることができます。
|
||||
|
||||
まず、カーネルソースコードからブート可能なカーネルをビルドできる能力が必要です。もしカーネルがオープンソースでない場合、あなたのデバイスで KernelSU を実行することは困難です。
|
||||
|
||||
ブート可能なカーネルをビルドできるなら、カーネルソースコードに KernelSU を統合する方法は二つあります:
|
||||
|
||||
1. `kprobe` で自動的に
|
||||
2. 手動で
|
||||
|
||||
## kprobe で統合する
|
||||
|
||||
KernelSU は kprobe を使ってカーネルフックを行います。もし *kprobe* があなたのカーネルでうまく動作する場合、この方法を使うことを推奨します。
|
||||
|
||||
まず、KernelSU をカーネルソースツリーに追加してください:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
次に、*kprobe* がカーネル設定で有効になっているか確認してください。もし有効でなければ、これらの設定を追加してください:
|
||||
|
||||
```
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
そしてカーネルを再度ビルドしてください。KernelSU はうまく動作するはずです。
|
||||
|
||||
KPROBES がまだ有効化されていない場合は、CONFIG_MODULES を有効化して試みることができます。(それでも効果がない場合は、make menuconfig を使って KPROBES の他の依存関係を検索してください)
|
||||
|
||||
しかし、KernelSU を統合した際にブートループに遭遇した場合、それは *kprobe* があなたのカーネルで破損している可能性があります。kprobe のバグを修正するか、二番目の方法を使用するべきです。
|
||||
|
||||
:::tip kprobe が破損しているかどうかを確認する方法は?
|
||||
|
||||
`KernelSU/kernel/ksu.c` にある `ksu_enable_sucompat()` と `ksu_enable_ksud()` をコメントアウトし、デバイスが正常にブートするか試してください。もし正常にブートするならば、kprobe が破損している可能性があります。
|
||||
|
||||
## カーネルソースを手動で変更する
|
||||
|
||||
もし kprobe があなたのカーネルで機能しない場合(上流のバグや 4.8 以下のカーネルバグが原因かもしれません)、以下の方法を試すことができます。
|
||||
|
||||
まず、KernelSU をカーネルソースツリーに追加してください:
|
||||
|
||||
::: code-group
|
||||
## カーネルソースを手動で変更する
|
||||
|
||||
もし kprobe があなたのカーネルで機能しない場合(上流のバグや 4.8 以下のカーネルバグが原因かもしれません)、以下の方法を試すことができます。
|
||||
|
||||
まず、KernelSU をカーネルソースツリーに追加してください:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
[ main branch(dev)]
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
[Select tag(Such as v0.5.2)]
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
いくつかのデバイスでは、あなたの defconfig が `arch/arm64/configs` にあったり、または他のケースでは `arch/arm64/configs/vendor/your_defconfig` にあることを念頭に置いてください。例えばあなたの defconfig で、`CONFIG_KSU` を y で有効に、または n で無効に設定します。あなたのパスは次のようになるでしょう:
|
||||
`arch/arm64/configs/...`
|
||||
```
|
||||
# KernelSU
|
||||
CONFIG_KSU=y
|
||||
```
|
||||
次に、KernelSU の呼び出しをカーネルソースに追加します。こちらは参照のためのパッチです:
|
||||
|
||||
::: code-group
|
||||
|
||||
```diff[exec.c]
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
+#endif
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ #endif
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff[open.c]
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff[read_write.c]
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
+#endif
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+ #endif
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff[stat.c]
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Get basic and extra attributes by filename
|
||||
* @dfd: A file descriptor representing the base dir for a relative filename
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
+ #endif
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
カーネル ソースには 4 つの関数があるはずです。
|
||||
|
||||
1. do_faccessat、通常は `fs/open.c` にあります
|
||||
2. do_execveat_common (通常は `fs/exec.c` にあります)
|
||||
3. vfs_read (通常は `fs/read_write.c` にあります)
|
||||
4. vfs_statx (通常は「fs/stat.c」にあります)
|
||||
|
||||
カーネルに `vfs_statx` がない場合は、代わりに `vfs_fstatat` を使用してください:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fstat);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int flag)
|
||||
{
|
||||
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = 0;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||
+ #endif
|
||||
+
|
||||
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH)) != 0)
|
||||
goto out;
|
||||
```
|
||||
|
||||
4.17 より前のカーネルの場合、`do faccessat` が見つからない場合は、`faccessat` システムコールの定義に移動して、そこで呼び出しを実行します。
|
||||
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 2ff887661237..e758d7db7663 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return error;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
+
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
KernelSU の組み込み SafeMode を有効にするには、`drivers/input/input.c` の `input_handle_event` も変更する必要があります。
|
||||
|
||||
:::ヒント
|
||||
この機能を有効にすることを強くお勧めします。ブートループを防ぐのに非常に役立ちます!
|
||||
:::
|
||||
|
||||
```diff
|
||||
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
||||
index 45306f9ef247..815091ebfca4 100755
|
||||
--- a/drivers/input/input.c
|
||||
+++ b/drivers/input/input.c
|
||||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev,
|
||||
return disposition;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_input_hook __read_mostly;
|
||||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);
|
||||
+#endif
|
||||
+
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition = input_get_disposition(dev, type, code, &value);
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_input_hook))
|
||||
+ ksu_handle_input_handle_event(&type, &code, &value);
|
||||
+ #endif
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
最後に、カーネルを再度ビルドすると、KernelSU が正常に動作するはずです。
|
||||
|
||||
:::info 誤ってセーフ モードに入ってしまった場合は、
|
||||
手動統合を使用し、`CONFIG_KPROBES` を無効にしない場合、ユーザーは起動後に音量を下げるボタンを押してセーフ モードをトリガーする可能性があります。 したがって、手動統合を使用する場合は、`CONFIG_KPROBES` を無効にする必要があります。
|
||||
:::
|
||||
@@ -1,274 +0,0 @@
|
||||
# インストール
|
||||
|
||||
## デバイスが対応しているか確認する
|
||||
|
||||
[GitHub Releases](https://github.com/tiann/KernelSU/releases) から KernelSU Manager アプリをダウンロードし、お使いのデバイスにインストールしてください。
|
||||
|
||||
- アプリが「非対応」と表示した場合は、**自分でカーネルをコンパイルする必要がある**という意味です。KernelSU は書き込むためのブートイメージを提供しません。
|
||||
- アプリが「未インストール」と表示した場合、お使いのデバイスは KernelSU に対応しています。
|
||||
|
||||
::: info ヒント
|
||||
非対応と表示されているデバイスについては、[非公式の対応デバイス](unofficially-support-devices.md)であればご自身でカーネルをビルドできます。
|
||||
:::
|
||||
|
||||
## 純正の boot.img をバックアップ
|
||||
|
||||
書き込む前に、まず純正の boot.img をバックアップする必要があります。ブートループが発生した場合は、fastboot を使用して純正のブートイメージを書き込むことでいつでもシステムを復旧できます。
|
||||
|
||||
::: warning 警告
|
||||
書き込みによりデータ損失を引き起こす可能性があります。次のステップに進む前に、このステップを必ず行うようにしてください!また、可能であればすべてのデータをバックアップしてください。
|
||||
:::
|
||||
|
||||
## 必要な知識
|
||||
|
||||
### ADB と fastboot
|
||||
|
||||
このチュートリアルでは、デフォルトで ADB と fastboot のツールを使用します。ご存じない方は、まず検索エンジンを使って勉強されることをおすすめします。
|
||||
|
||||
### KMI
|
||||
|
||||
同じ Kernel Module Interface (KMI) のカーネルバージョンは**互換性があります**。これが GKI の「汎用」という意味です。逆に言えば KMI が異なればカーネルには互換性がなく、お使いのデバイスと異なる KMI のカーネルイメージを書き込むと、ブートループが発生する場合があります。
|
||||
|
||||
具体的には GKI デバイスの場合、カーネルバージョンの形式は以下のようになります:
|
||||
|
||||
```txt
|
||||
KernelRelease :=
|
||||
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
|
||||
w .x .y -zzz -k -something
|
||||
```
|
||||
|
||||
`w.x-zzz-k` は KMI のバージョンです。例えば、デバイスのカーネルバージョンが `5.10.101-android12-9-g30979850fc20` である場合、その KMIは `5.10-android12-9` であり、理論的には他の KMI カーネルでも正常に起動できます。
|
||||
|
||||
::: tip ヒント
|
||||
カーネルバージョンの SubLevel は、KMI の一部ではないことに注意してください。`5.10.101-android12-9-g30979850fc20` は `5.10.137-android12-9-g30979850fc20` と同じ KMI を持っているということになります。
|
||||
:::
|
||||
|
||||
### セキュリティパッチレベル {#security-patch-level}
|
||||
|
||||
新しめの Android 端末には、セキュリティパッチレベルが古い boot イメージのフラッシュを許可しないロールバック防止機構が導入されていることがあります。例えば、もしあなたの端末のカーネルが `5.10.101-android12-9-g30979850fc20` であれば、セキュリティパッチレベルは `2023-11` です。たとえ KMI に対応するカーネルをフラッシュしても、セキュリティパッチレベルが (`2023-06` のように) `2023-11` より低い場合、ブートループを起こす可能性があります。
|
||||
|
||||
### Kernel バージョンと Android バージョンの違い
|
||||
|
||||
注意: **カーネルバージョンと Android バージョンは必ずしも同じではありません**。
|
||||
|
||||
カーネルのバージョンは「android12-5.10.101」なのに、Android システムのバージョンは「Android 13」などとなっている場合、驚かないでください。Linux カーネルのバージョン番号は、必ずしも**デバイスの出荷時**にプリインストールされている Android システムのバージョンと一致していません。Android システムが後でアップグレードされた場合、一般的にはカーネルのバージョンは変更されません。書き込む際は、**必ずカーネルバージョンを参照してください**!!!
|
||||
|
||||
## はじめに
|
||||
|
||||
バージョン [0.9.0](https://github.com/tiann/KernelSU/releases/tag/v0.9.0) 以降、KernelSU は GKI 端末において 2 つの動作モードに対応しています。
|
||||
|
||||
1. `GKI`: 端末本来のカーネルを KernelSU によって提供される **汎用カーネルイメージ** (GKI) で置き換えます。
|
||||
2. `LKM`: 端末本来のカーネルを置き換えずに、カーネルに **ローダブルカーネルモジュール** (LKM) を読み込みます。
|
||||
|
||||
これらの 2 つのモードはそれぞれ異なる状況に適しており、必要に応じてどちらかを選ぶことができます。
|
||||
|
||||
### GKI モード {#gki-mode}
|
||||
|
||||
GKI モードでは、端末本来のカーネルは KernelSU によって提供される汎用カーネルイメージによって置き換えられます。GKI モードの利点は:
|
||||
|
||||
1. 強い汎用性があり、大部分の端末に適合。例えば、Samsung 端末は KNOX が有効であり、LKM モードは動作できません。また、GKI モードしか使えないニッチな改造を施された端末もあります。
|
||||
2. 公式ファームウェアに依存せずに使うことができます。KMI が一致している限り、公式ファームウェアの更新を待つことなく使うことができます。
|
||||
|
||||
### LKM モード {#lkm-mode}
|
||||
|
||||
LKM モードでは、端末本来のカーネルを置き換えずに、カーネルにローダブルカーネルモジュールを読み込みます。LKM モードの利点は:
|
||||
|
||||
1. 端末本来のカーネルを置き換えません。端末本来のカーネルに特別な要件がある場合や、KernelSU をサードパーティのカーネルと両用したい場合、LKM モードを利用できます。
|
||||
2. アップグレードと OTA がより便利です。KernelSU をアップデートする時は、手動でフラッシュすることなくマネージャーから直接インストールできます。システム OTA の後は、手動でフラッシュすることなく非アクティブなスロットに直接インストールすることができます。
|
||||
3. いくつかの特殊な状況に適しています。例えば、LKM は一時的な Root 権限を用いて読み込むことができます。boot パーティションを置き換えないので、AVB を動作させず、端末を文鎮化しません。
|
||||
4. LKM は一時的にアンインストールすることができます。一時的に root アクセスを無効化したい場合、LKM をアンインストールすることができます。この過程でパーティションをフラッシュすることも、また再起動することさえも必要ありません。root アクセスを再度有効化したい場合は、再起動するだけです。
|
||||
|
||||
:::tip 2 つのモードの共存
|
||||
マネージャーを開くと、ホームで現在の端末の動作モードを確認できます。GKI モードの優先度は LKM モードより高いことに留意してください。例えば、本来のカーネルを GKI カーネルで置き換えたうえで LKM を使って GKI カーネルにパッチしている場合、LKM は無視され、端末は常時 GKI モードで動作します。
|
||||
:::
|
||||
|
||||
### どちらを選ぶべきですか? {#which-one}
|
||||
|
||||
端末が携帯電話の場合、LKM モードを優先することを推奨します。端末がエミュレーター、WSA、または Waydroid の場合、GKI モードを優先することを推奨します。
|
||||
|
||||
## LKM モードのインストール
|
||||
|
||||
### 公式ファームウェアの入手
|
||||
|
||||
LKM モードを使うためには、公式ファームウェアを入手し、それを基にパッチを当てる必要があります。サードパーティのカーネルを使う場合、その `boot.img` を公式ファームウェアとして利用できます。
|
||||
|
||||
公式ファームウェアを入手する方法はたくさんあります。端末が `fastboot boot` に対応している場合、`fastboot boot` を使って一時的に KernelSU が提供する GKI カーネルを起動する、 **最も推奨される、最も簡単な** 方法を推奨します。
|
||||
|
||||
端末が `fastboot boot` に対応していない場合、公式ファームウェアのパッケージを手動でダウンロードし、そこから `boot.img` を展開する必要があります。
|
||||
|
||||
GKI モードとは異なり、LKM モードは `ramdisk` を展開します。そのため、Android 13 の端末では `boot` パーティションの代わりに `init_boot` パーティションにパッチを当てる必要があります。一方で、GKI モードは常に `boot` パーティションを操作します。
|
||||
|
||||
### マネージャーを使う
|
||||
|
||||
マネージャーを開き、右上のインストールアイコンをタップすると、いくつかのオプションが現れます:
|
||||
|
||||
1. ファイルを選択しパッチを当てる。端末が Root 権限を持っていない場合、このオプションを選択し、公式ファームウェアを選択すると、マネージャーが自動的にパッチを当てます。恒久的に Root 権限を獲得するには、パッチが当てられたファイルをフラッシュするだけです。
|
||||
2. 直接インストール。端末が既に Root 化されている場合、このオプションを選択すると、マネージャーが自動的に端末の情報を取得し、自動的に公式ファームウェアにパッチを当て、それをフラッシュします。`fastboot boot` で KernelSU の GKI を起動し一時的に Root 権限を獲得したうえでこのオプションを利用することもできます。これは KernelSU をアップグレードする主な方法でもあります。
|
||||
3. 非アクティブなスロットにインストール。端末が A/B パーティションに対応している場合、このオプションを選択すると、マネージャーが自動的に公式ファームウェアにパッチを当て、もう一方のパーティションにインストールします。この方法は OTA 後の端末に適しており、OTA 後にもう一方のパーティションに直接 KernelSU をインストールし、端末を再起動することができます。
|
||||
|
||||
### コマンドラインを使う
|
||||
|
||||
マネージャーを使いたくない場合、コマンドラインを使って LKM をインストールできます。KernelSU の提供する `ksud` ツールを使うと、迅速に公式ファームウェアにパッチを当てフラッシュすることができます。
|
||||
|
||||
このツールは macOS、Linux および Windows に対応しています。[GitHub Release](https://github.com/tiann/KernelSU/releases) から対応するバージョンをダウンロードしてください。
|
||||
|
||||
使用方法: `ksud bootpatch` コマンドの各オプションのヘルプをコマンドラインから確認できます。
|
||||
```sh
|
||||
oriole:/ # ksud boot-patch -h
|
||||
Patch boot or init_boot images to apply KernelSU
|
||||
|
||||
Usage: ksud boot-patch [OPTIONS]
|
||||
|
||||
Options:
|
||||
-b, --boot <BOOT> boot image path, if not specified, will try to find the boot image automatically
|
||||
-k, --kernel <KERNEL> kernel image path to replace
|
||||
-m, --module <MODULE> LKM module path to replace, if not specified, will use the builtin one
|
||||
-i, --init <INIT> init to be replaced
|
||||
-u, --ota will use another slot when boot image is not specified
|
||||
-f, --flash Flash it to boot partition after patch
|
||||
-o, --out <OUT> output path, if not specified, will use current directory
|
||||
--magiskboot <MAGISKBOOT> magiskboot path, if not specified, will use builtin one
|
||||
--kmi <KMI> KMI version, if specified, will use the specified KMI
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
説明が必要ないくつかのオプション:
|
||||
|
||||
1. `--magiskboot` オプションは magiskboot のパスを指定します。指定されていない場合、ksud は環境変数を参照します。magiskboot の入手方法がわからない場合、[こちら](#patch-boot-image) を参照してください。
|
||||
2. `--kmi` オプションは `KMI` バージョンを指定します。端末のカーネル名が KMI の仕様に準拠していない場合は、このオプションで指定することができます。
|
||||
|
||||
最も一般的な使い方:
|
||||
|
||||
```sh
|
||||
ksud boot-patch -b <boot.img> --kmi android13-5.10
|
||||
```
|
||||
|
||||
## GKI モードのインストール
|
||||
|
||||
GKI モードのインストール方法はいくつかあり、それぞれ適したシーンが異なりますので、必要に応じて選択してください。
|
||||
|
||||
1. KernelSU が提供する boot.img を使用し、fastboot でインストールする
|
||||
2. KernelFlasher などのカーネル管理アプリでインストールする
|
||||
3. boot.img を手動でパッチしてインストールする
|
||||
4. カスタムリカバリー(TWRPなど)でインストールする
|
||||
|
||||
## KernelSU が提供する boot.img を使用してインストール
|
||||
|
||||
この方法は TWRP や root 権限を必要としないので、KernelSU を初めてインストールする場合に適しています。
|
||||
|
||||
### 正しい boot.img を見つける
|
||||
|
||||
KernelSU では、GKI デバイス用の汎用 boot.img を提供しています。デバイスの boot パーティションに boot.img をフラッシュする必要があります。
|
||||
|
||||
boot.img は、[GitHub Release](https://github.com/tiann/KernelSU/releases) からダウンロードできます。例えば、あなたのデバイスがカーネル `android12-5.10.101` の場合、`android-5.10.101_yyyy-MM.boot-<format>.img`をダウンロードする必要があります。(KMI を同じにしてください!)。
|
||||
|
||||
`<format>`は純正 boot.img のカーネル圧縮形式を指します。純正の boot.img のカーネル圧縮形式を確認してください。間違った圧縮形式を使うと、ブートループするかもしれません。
|
||||
|
||||
::: info 情報
|
||||
1. magiskboot を使えば、元のブートの圧縮形式を知ることができます。もちろん、あなたのデバイスと同じモデルを持つ、より経験豊富な他の人にも聞くこともできます。また、カーネルの圧縮形式は通常変更されないので、ある圧縮形式でうまく起動した場合、後でその形式を試すことも可能です。
|
||||
2. Xiaomi デバイスでは通常 `gz` か**無圧縮**が使われます。
|
||||
3. Pixel デバイスでは以下の手順に従ってください。
|
||||
:::
|
||||
|
||||
### boot.img をデバイスに書き込む
|
||||
|
||||
`adb` でデバイスを接続し、`adb reboot bootloader` で fastboot モードにし、このコマンドで KernelSU を書き込んでください:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
::: info 情報
|
||||
デバイスが `fastboot boot` をサポートしている場合、まず `fastboot boot.img` を使えば書き込みせずにシステムを起動できます。予期せぬことが起こった場合は、もう一度再起動して起動してください。
|
||||
:::
|
||||
|
||||
### 再起動
|
||||
|
||||
書き込みが完了したら、デバイスを再起動します:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
## カーネル管理アプリでインストール
|
||||
|
||||
前提条件:お使いのデバイスが root 化されている必要があります。例えば、Magisk をインストールして root を取得した場合、または古いバージョンの KernelSU をインストールしており、別のバージョンの KernelSU にアップグレードする必要がある場合などです。お使いのデバイスが root 化されていない場合、他の方法をお試しください。
|
||||
|
||||
手順:
|
||||
|
||||
1. AnyKernel3 ZIP をダウンロードします。ダウンロード方法は、「カスタムリカバリーでインストール」を参照してください。
|
||||
2. カーネル管理アプリを開き、AnyKernel3 の ZIP をインストールします。
|
||||
|
||||
カーネル管理アプリは以下のようなものが人気です:
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
この方法は KernelSU をアップグレードするときに便利で、パソコンがなくてもできます。(まずはバックアップしてください!)
|
||||
|
||||
## boot.img を手動でパッチ {#patch-boot-image}
|
||||
|
||||
デバイスによっては、boot.img のフォーマットが `lz4` でない、`gz` である、無圧縮であるなど、あまり一般的でないことがあります。最も典型的なのは Pixel で、boot.img フォーマットは `lz4_legacy` 圧縮、RAM ディスクは `gz` か `lz4_legacy` 圧縮です。この時、KernelSU が提供した boot.img を直接書き込むとデバイスが起動できなくなる場合があります。その場合は手動で boot.img に対してパッチしてください。
|
||||
|
||||
常に `magiskboot` を利用してイメージにパッチを当てることが推奨されます。2 つの方法があります:
|
||||
|
||||
1. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
2. [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci)
|
||||
|
||||
公式の `magisikboot` ビルドは Android 端末でしか動作しないため、PC で作業したい場合、2 つめの方法を試してください。
|
||||
|
||||
:::tip
|
||||
Android-Image-Kitchen は現在非推奨です。セキュリティパッチレベルなどの boot メタデータを正しく扱わないため、一部のデバイスでは動作しない可能性があります。
|
||||
:::
|
||||
|
||||
### 準備
|
||||
|
||||
1. お使いのデバイスの純正 boot.img を入手します。デバイスメーカーから入手できます。[payload-dumper-go](https://github.com/ssut/payload-dumper-go)が必要かもしれません。
|
||||
2. お使いのデバイスの KMI バージョンに合った、KernelSU が提供する AnyKernel3 の ZIP ファイルをダウンロードします(*カスタムリカバリーでインストール*を参照してください)。
|
||||
3. AnyKernel3 パッケージを展開し、KernelSU のカーネルファイルである `Image` ファイルを取得します。
|
||||
|
||||
### Android 端末で magiskboot を使う {#using-magiskboot-on-Android-devices}
|
||||
|
||||
1. 最新の Magisk を[リリースページ](https://github.com/topjohnwu/Magisk/releases)からダウンロードしてください。
|
||||
2. `Magisk-*(version).apk` を `Magisk-*.zip` に名前を変更して展開してください。
|
||||
3. `Magisk-*/lib/arm64-v8a/libmagiskboot.so`を adb でデバイスに転送します:`adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot`
|
||||
4. 純正 boot.img と AnyKernel3 の中の Image をデバイスに転送します。
|
||||
5. adb shell に入り、`cd /data/local/tmp/` し、`chmod +x magiskboot` を実行します。
|
||||
6. adb shell に入り、`cd /data/local/tmp/` し、`./magiskboot unpack boot.img` を実行して `boot.img` を抽出します。`kernel` ファイルが純正カーネルです。
|
||||
7. `kernel` を `Image` で置き換えます: `mv -f Image kernel`
|
||||
8. `./magiskboot repack boot.img` を実行してブートイメージをリパックします。出来上がった `new-boot.img` を fastboot でデバイスに書き込んでください。
|
||||
|
||||
### Windows/macOS/Linux PC で magiskboot を使う {#using-magiskboot-on-PC}
|
||||
|
||||
1. OS に対応する `magiskboot` バイナリを [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci) からダウンロードします。
|
||||
2. 純正の `boot.img` と `Image` を PC 上に準備します。
|
||||
3. `chmod +x magiskboot` を実行します。
|
||||
4. 対応するディレクトリに入り、`./magiskboot unpack boot.img` を実行して `boot.img` を展開します。展開された `kernel` ファイルが純正のカーネルです。
|
||||
5. 下記のコマンドを実行し、`kernel` を `Image` で置き換えてください: `mv -f Image kernel`
|
||||
6. `./magiskboot repack boot.img` を実行し、boot イメージを再パックします。作成された `new-boot.img` ファイルを、fastboot を利用して端末にフラッシュします。
|
||||
|
||||
::: info
|
||||
公式の `magiskboot` は、`Linux` 環境においては正常に動作します。Linux を使っている場合、公式のビルドを利用できます。
|
||||
:::
|
||||
|
||||
## カスタムリカバリーでインストール {#install-with-custom-recovery}
|
||||
|
||||
前提条件:デバイスに TWRP などのカスタムリカバリーがあること。ない場合、または公式リカバリーしかない場合は他の方法を使用してください。
|
||||
|
||||
手順:
|
||||
|
||||
1. KernelSUの[リリースページ](https://github.com/tiann/KernelSU/releases)から、お使いのデバイスのバージョンにあった AnyKernel3 で始まる ZIP パッケージをダウンロードします。例えば、デバイスのカーネルのバージョンが`android12-5.10. 66`の場合、AnyKernel3-android12-5.10.66_yyyy-MM.zip`(yyyy`は年、`MM`は月)のファイルをダウンロードします。
|
||||
2. デバイスを TWRP へ再起動します。
|
||||
3. adb を使用して AnyKernel3-*.zip をデバイスの /sdcard に入れ、TWRP GUI でインストールを選択します。または直接`adb sideload AnyKernel-*.zip` でインストールできます。
|
||||
|
||||
この方法は TWRP を使用できるならどのようなインストール(初期インストールやその後のアップグレード)にも適しています。
|
||||
|
||||
## その他の方法
|
||||
|
||||
実はこれらのインストール方法はすべて、**元のカーネルを KernelSU が提供するカーネルに置き換える**という主旨でしかなく、これが実現できれば他の方法でもインストール可能です:
|
||||
|
||||
1. まず Magisk をインストールし、Magisk を通じて root 権限を取得し、カーネル管理アプリで KernelSU の AnyKernel ZIPをインストールする
|
||||
2. PC 上で何らかの書き込みツールを使用し、KernelSU が提供するカーネルを書き込む
|
||||
|
||||
しかし、これらの方法でうまく行かない場合、`magiskboot` を使う方法を試してみてください。
|
||||
@@ -1,48 +0,0 @@
|
||||
# Module WebUI
|
||||
|
||||
KernelSU のモジュールは、ブートスクリプトの実行やシステムファイルの修正に加えて、UI インターフェースの表示やユーザーとの対話もサポートしています。
|
||||
|
||||
モジュールは、任意の Web 技術を通じて HTML + CSS + JavaScript のページを作成することができます。KernelSU のマネージャーは WebView を通じてこれらのページを表示します。また、シェルコマンドの実行など、システムと対話するためのいくつかのAPIを提供しています。
|
||||
|
||||
## `webroot` ディレクトリ
|
||||
|
||||
Web リソースファイルは、モジュールのルートディレクトリの `webroot` サブディレクトリに置かれるべきであり、`index.html` という名前のファイルが必ず存在しなければなりません。これがモジュールページのエントリです。Web インターフェイスを含む最もシンプルなモジュール構造は以下の通りです:
|
||||
|
||||
```txt
|
||||
❯ tree .
|
||||
.
|
||||
|-- module.prop
|
||||
`-- webroot
|
||||
`-- index.html
|
||||
```
|
||||
|
||||
:::警告
|
||||
モジュールをインストールするとき、KernelSU はこのディレクトリのパーミッションと SELinux コンテキストを自動的に設定します。何をしているかわからないのであれば、自分でこのディレクトリのパーミッションを設定しないでください!
|
||||
:::
|
||||
|
||||
ページに css や JavaScript が含まれている場合は、このディレクトリに配置する必要があります。
|
||||
|
||||
## JavaScript API
|
||||
|
||||
単なる表示ページであれば、通常の Web ページとの違いはありません。より重要なのは、KernelSU がモジュールの固有機能を実装させるための一連のシステム API を提供することです。
|
||||
|
||||
KernelSU は JavaScript ライブラリを提供し、[npm で公開しています](https://www.npmjs.com/package/kernelsu)。これを Web ページの JavaScript コードで使用することができます。
|
||||
|
||||
たとえば、特定の設定を取得したり、プロパティを変更するために、シェルコマンドを実行することができます:
|
||||
|
||||
```JavaScript
|
||||
import { exec } from 'kernelsu';
|
||||
|
||||
const { errno, stdout } = exec("getprop ro.product.model");
|
||||
```
|
||||
|
||||
別の例として、Webページをフルスクリーンで表示したり、トーストを表示することができます。
|
||||
|
||||
[API ドキュメント](https://www.npmjs.com/package/kernelsu)
|
||||
|
||||
既存のAPIがご自身のニーズを満たしていない、または使い勝手が不便である場合、[こちら](https://github.com/tiann/KernelSU/issues)でご提案いただければ幸いです!
|
||||
|
||||
## いくつかのヒント
|
||||
|
||||
1. `localStorage` を通常通りに使用してデータを保存することができますが、Manager アプリをアンインストールした後には失われます。永続的に保存する必要がある場合は、自分でいくつかのディレクトリにデータを書き込むことができます。
|
||||
2. シンプルなページには、[parceljs](https://parceljs.org/)を使用することをお勧めします。設定が不要で非常に便利です。しかし、フロントエンドの達人である場合や、自分の好みがある場合は、気に入ったものを選んでください!
|
||||
@@ -1,255 +0,0 @@
|
||||
# モジュールのガイド
|
||||
|
||||
KernelSU はシステムパーティションの整合性を維持しながら、システムディレクトリを変更する効果を実現するモジュール機構を提供します。この機構は一般に「システムレス」と呼ばれています。
|
||||
|
||||
KernelSU のモジュール機構は、Magisk とほぼ同じです。Magisk のモジュール開発に慣れている方であれば、KernelSU のモジュール開発も簡単でしょう。その場合は以下のモジュールの紹介は読み飛ばして、[Magisk との違い](difference-with-magisk.md)の内容だけ読めばOKです。
|
||||
|
||||
## Busybox
|
||||
|
||||
KernelSU には、機能的に完全な Busybox バイナリ (SELinux の完全サポートを含む) が同梱されています。実行ファイルは `/data/adb/ksu/bin/busybox` に配置されています。KernelSU の Busybox はランタイムに切り替え可能な「ASH スタンドアローンシェルモード」をサポートしています。このスタンドアロンモードとは、Busybox の `ash` シェルで実行する場合 `PATH` として設定されているものに関係なく、すべてのコマンドが Busybox 内のアプレットを直接使用するというものです。たとえば、`ls`、`rm`、`chmod` などのコマンドは、`PATH` にあるもの(Android の場合、デフォルトではそれぞれ `/system/bin/ls`, `/system/bin/rm`, `/system/bin/chmod`)ではなく、直接 Busybox 内部のアプレットを呼び出すことになります。これにより、スクリプトは常に予測可能な環境で実行され、どの Android バージョンで実行されていても常にコマンドを利用できます。Busybox を使用しないコマンドを強制的に実行するには、フルパスで実行ファイルを呼び出す必要があります。
|
||||
|
||||
KernelSU のコンテキストで実行されるすべてのシェルスクリプトは、Busybox の `ash` シェルでスタンドアロンモードが有効な状態で実行されます。サードパーティの開発者に関係するものとしては、すべてのブートスクリプトとモジュールのインストールスクリプトが含まれます。
|
||||
|
||||
この「スタンドアロンモード」機能を KernelSU 以外で使用したい場合、2つの方法で有効にできます:
|
||||
|
||||
1. 環境変数 `ASH_STANDALONE` を `1` にする<br>例: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. コマンドラインのオプションで変更する:<br>`/data/adb/ksu/bin/busybox sh -o standalone <script>`
|
||||
|
||||
環境変数が子プロセスに継承されるため、その後に実行されるすべての `sh` シェルもスタンドアロンモードで実行されるようにするにはオプション 1 が望ましい方法です(KernelSU と KernelSU Managerが内部的に使用しているのもこちらです)。
|
||||
|
||||
::: tip Magisk との違い
|
||||
|
||||
KernelSU の Busybox は、Magisk プロジェクトから直接コンパイルされたバイナリファイルを使用するようになりました。Magisk と KernelSU の Busybox スクリプトはまったく同じものなので、互換性の問題を心配する必要はありません!
|
||||
:::
|
||||
|
||||
## KernelSU モジュール
|
||||
|
||||
KernelSU モジュールは、`/data/adb/modules` に配置された以下の構造を持つフォルダーです:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- フォルダの名前はモジュールの ID で付けます
|
||||
│ │
|
||||
│ │ *** モジュールの ID ***
|
||||
│ │
|
||||
│ ├── module.prop <--- このファイルにモジュールのメタデータを保存します
|
||||
│ │
|
||||
│ │ *** メインコンテンツ ***
|
||||
│ │
|
||||
│ ├── system <--- skip_mount が存在しない場合、このフォルダがマウントされます
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** ステータスフラグ ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- 存在する場合、KernelSU はシステムフォルダをマウントしません
|
||||
│ ├── disable <--- 存在する場合、モジュールは無効化されます
|
||||
│ ├── remove <--- 存在する場合、次の再起動時にモジュールが削除されます
|
||||
│ │
|
||||
│ │ *** 任意のファイル ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- このスクリプトは post-fs-data で実行されます
|
||||
│ ├── service.sh <--- このスクリプトは late_start サービスで実行されます
|
||||
| ├── uninstall.sh <--- このスクリプトは KernelSU がモジュールを削除するときに実行されます
|
||||
│ ├── system.prop <--- このファイルのプロパティは resetprop によってシステムプロパティとして読み込まれます
|
||||
│ ├── sepolicy.rule <--- カスタム SEPolicy ルールを追加します
|
||||
│ │
|
||||
│ │ *** 自動生成されるため、手動で作成または変更しないでください ***
|
||||
│ │
|
||||
│ ├── vendor <--- $MODID/system/vendor へのシンボリックリンク
|
||||
│ ├── product <--- $MODID/system/product へのシンボリックリンク
|
||||
│ ├── system_ext <--- $MODID/system/system_ext へのシンボリックリンク
|
||||
│ │
|
||||
│ │ *** その他のファイル/フォルダの追加も可能です ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: tip Magisk との違い
|
||||
KernelSU は Zygisk をビルトインでサポートしていないため、モジュール内に Zygisk に関連するコンテンツは存在しません。 しかし、[ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) をインストールすれば Zygisk モジュールを使えます。その場合の Zygisk モジュールのコンテンツは Magisk と同じです。
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
module.prop はモジュールの設定ファイルです。KernelSU ではこのファイルを含まないモジュールは、モジュールとして認識されません。このファイルの形式は以下の通りです:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versionCode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` はこの正規表現に一致していなければいけません: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
例: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
これはモジュールの**ユニークな ID** です。公開後は変更しないでください。
|
||||
- `versionCode` は **integer** です。バージョンの比較に使います。
|
||||
- 他のものには**単一行** の文字であれば何でも使えます。
|
||||
- 改行文字は `UNIX (LF)` を使ってください。`Windows (CR+LF)` や `Macintosh (CR)` は使ってはいけません。
|
||||
|
||||
### シェルスクリプト
|
||||
|
||||
`post-fs-data.sh` と `service.sh` の違いについては、[ブートスクリプト](#boot-scripts)のセクションを読んでください。ほとんどのモジュール開発者にとって、ブートスクリプトを実行するだけなら `service.sh` で十分なはずです。
|
||||
|
||||
モジュールのすべてのスクリプトでは、`MODDIR=${0%/*}`を使えばモジュールのベースディレクトリのパスを取得できます。スクリプト内でモジュールのパスをハードコードしないでください。
|
||||
|
||||
::: tip Magisk との違い
|
||||
環境変数 `KSU` を使用すると、スクリプトが KernelSU と Magisk どちらで実行されているかを判断できます。KernelSU で実行されている場合、この値は `true` に設定されます。
|
||||
:::
|
||||
|
||||
### `system` ディレクトリ
|
||||
|
||||
このディレクトリの内容は、システムの起動後に OverlayFS を使用してシステムの /system パーティションの上にオーバーレイされます:
|
||||
|
||||
1. システム内の対応するディレクトリにあるファイルと同名のファイルは、このディレクトリにあるファイルで上書きされます。
|
||||
2. システム内の対応するディレクトリにあるフォルダと同じ名前のフォルダは、このディレクトリにあるフォルダと統合されます。
|
||||
|
||||
元のシステムディレクトリにあるファイルやフォルダを削除したい場合は、`mknod filename c 0 0` を使ってモジュールディレクトリにそのファイル/フォルダと同じ名前のファイルを作成する必要があります。こうすることで、OverlayFS システムはこのファイルを削除したかのように自動的に「ホワイトアウト」します(/system パーティションは実際には変更されません)。
|
||||
|
||||
また、`customize.sh` 内で `REMOVE` という変数に削除操作を実行するディレクトリのリストを宣言すると、KernelSU は自動的にそのモジュールの対応するディレクトリで `mknod <TARGET> c 0 0` を実行します。例えば
|
||||
|
||||
```sh
|
||||
REMOVE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
上記の場合は、`mknod $MODPATH/system/app/YouTuBe c 0 0`と`mknod $MODPATH/system/app/Bloatware c 0 0`を実行し、`/system/app/YouTube`と`/system/app/Bloatware`はモジュール有効化後に削除されます。
|
||||
|
||||
システム内のディレクトリを置き換えたい場合は、モジュールディレクトリに同じパスのディレクトリを作成し、このディレクトリに `setfattr -n trusted.overlay.opaque -v y <TARGET>` という属性を設定する必要があります。こうすることで、OverlayFS システムは(/system パーティションを変更することなく)システム内の対応するディレクトリを自動的に置き換えることができます。
|
||||
|
||||
`customize.sh` ファイル内に `REPLACE` という変数を宣言し、その中に置換するディレクトリのリストを入れておけば、KernelSU は自動的にモジュールディレクトリに対応した処理を行います。例えば:
|
||||
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
|
||||
このリストは、自動的に `$MODPATH/system/app/YouTube` と `$MODPATH/system/app/Bloatware` というディレクトリを作成し、 `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` と `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware` を実行します。モジュールが有効になると、`/system/app/YouTube` と `/system/app/Bloatware` は空のディレクトリに置き換えられます。
|
||||
|
||||
::: tip Magisk との違い
|
||||
|
||||
KernelSU のシステムレスメカニズムはカーネルの OverlayFS によって実装され、Magisk は現在マジックマウント(bind mount)を使用しています。この2つの実装方法には大きな違いがありますが最終的な目的は同じで、/system パーティションを物理的に変更することなく、/system のファイルを変更できます。
|
||||
:::
|
||||
|
||||
OverlayFS に興味があれば、Linux カーネルの [OverlayFS のドキュメンテーション](https://docs.kernel.org/filesystems/overlayfs.html) を読んでみてください。
|
||||
|
||||
### system.prop
|
||||
|
||||
このファイルは `build.prop` と同じ形式をとっています。各行は `[key]=[value]` で構成されます。
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
もしあなたのモジュールが追加の SEPolicy パッチを必要とする場合は、それらのルールをこのファイルに追加してください。このファイルの各行は、ポリシーステートメントとして扱われます。
|
||||
|
||||
## モジュールのインストーラー
|
||||
|
||||
KernelSU モジュールインストーラーは、KernelSU Manager アプリでインストールできる、ZIP ファイルにパッケージされた KernelSU モジュールです。最もシンプルな KernelSU モジュールインストーラーは、KernelSU モジュールを ZIP ファイルとしてパックしただけのものです。
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (任意、詳細は後述)
|
||||
│ このスクリプトは update-binary から読み込まれます
|
||||
├── ...
|
||||
├── ... /* 残りのモジュールのファイル */
|
||||
│
|
||||
```
|
||||
|
||||
::: warning 警告
|
||||
KernelSU モジュールは、カスタムリカバリーからのインストールには非対応です!
|
||||
:::
|
||||
|
||||
### カスタマイズ
|
||||
|
||||
モジュールのインストールプロセスをカスタマイズする必要がある場合、`customize.sh` という名前のスクリプトを作成してください。このスクリプトは、すべてのファイルが抽出され、デフォルトのパーミッションと secontext が適用された後、モジュールインストーラースクリプトによって読み込み (実行ではなく) されます。これは、モジュールがデバイスの ABI に基づいて追加設定を必要とする場合や、モジュールファイルの一部に特別なパーミッション/コンテキストを設定する必要がある場合に、非常に便利です。
|
||||
|
||||
インストールプロセスを完全に制御しカスタマイズしたい場合は、`customize.sh` で `SKIPUNZIP=1` と宣言すればデフォルトのインストールステップをすべてスキップできます。そうすることで、`customize.sh` が責任をもってすべてをインストールするようになります。
|
||||
|
||||
`customize.sh`スクリプトは、KernelSU の Busybox `ash` シェルで、「スタンドアロンモード」を有効にして実行します。以下の変数と関数が利用可能です:
|
||||
|
||||
#### 変数
|
||||
|
||||
- `KSU` (bool): スクリプトが KernelSU 環境で実行されていることを示すための変数で、この変数の値は常に true になります。KernelSU と Magisk を区別するために使用できます。
|
||||
- `KSU_VER` (string): 現在インストールされている KernelSU のバージョン文字列 (例: `v0.4.0`)
|
||||
- `KSU_VER_CODE` (int): ユーザー空間に現在インストールされているKernelSUのバージョンコード (例: `10672`)
|
||||
- `KSU_KERNEL_VER_CODE` (int): 現在インストールされている KernelSU のカーネル空間でのバージョンコード(例:`10672`)
|
||||
- `BOOTMODE` (bool): KernelSU では常に `true`
|
||||
- `MODPATH` (path): モジュールファイルがインストールされるパス
|
||||
- `TMPDIR` (path): ファイルを一時的に保存しておく場所
|
||||
- `ZIPFILE` (path): あなたのモジュールのインストールZIP
|
||||
- `ARCH` (string): デバイスの CPU アーキテクチャ。値は `arm`、`arm64`、`x86`、`x64` のいずれか
|
||||
- `IS64BIT` (bool): `ARCH` が `arm64` または `x64` のときは `true`
|
||||
- `API` (int): 端末の API レベル・Android のバージョン(例:Android 6.0 なら`23`)
|
||||
|
||||
::: warning 警告
|
||||
KernelSU では、MAGISK_VER_CODE は常に25200、MAGISK_VER は常にv25.2です。この2つの変数で KernelSU 上で動作しているかどうかを判断するのはやめてください。
|
||||
:::
|
||||
|
||||
#### 機能
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
コンソールに <msg> を表示します
|
||||
カスタムリカバリーのコンソールでは表示されないため、「echo」の使用は避けてください
|
||||
|
||||
abort <msg>
|
||||
エラーメッセージ<msg>をコンソールに出力し、インストールを終了させます
|
||||
終了時のクリーンアップがスキップされてしまうため、「exit」の使用は避けてください
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
[context] が設定されていない場合、デフォルトは "u:object_r:system_file:s0" です。
|
||||
この機能は、次のコマンドの略記です:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
[context] が設定されていない場合、デフォルトは "u:object_r:system_file:s0" です。
|
||||
<directory> 内のすべてのファイルに対しては以下が実行されます:
|
||||
set_perm file owner group filepermission context
|
||||
<directory> 内のすべてのディレクトリ(自身を含む)に対しては以下が実行されます:
|
||||
set_perm dir owner group dirpermission context
|
||||
```
|
||||
|
||||
## ブートスクリプト
|
||||
|
||||
KernelSU では、スクリプトは実行モードによって post-fs-data モードと late_start サービスモードの2種類に分けられます:
|
||||
|
||||
- post-fs-data モード
|
||||
- 同期処理です。実行が終わるか、10秒が経過するまでブートプロセスが一時停止されます。
|
||||
- スクリプトはモジュールがマウントされる前に実行されます。モジュール開発者はモジュールがマウントされる前に、動的にモジュールを調整できます。
|
||||
- このステージは Zygote が始まる前に起こるので、Android のほぼすべての処理の前に割り込めます
|
||||
- **警告:** `setprop` を使うとブートプロセスのデッドロックを引き起こします! `resetprop -n <prop_name> <prop_value>` を使ってください。
|
||||
- **本当に必要な場合だけこのモードでコマンド実行してください**
|
||||
- late_start サービスモード
|
||||
- 非同期処理です。スクリプトは、起動プロセスの残りの部分と並行して実行されます。
|
||||
- **ほとんどのスクリプトにはこちらがおすすめです**
|
||||
|
||||
KernelSU では、起動スクリプトは保存場所によって一般スクリプトとモジュールスクリプトの2種類に分けられます:
|
||||
|
||||
- 一般スクリプト
|
||||
- `/data/adb/post-fs-data.d` か `/data/adb/service.d` に配置されます
|
||||
- スクリプトが実行可能な状態に設定されている場合にのみ実行されます (`chmod +x script.sh`)
|
||||
- `post-fs-data.d` のスクリプトは post-fs-data モードで実行され、`service.d` のスクリプトは late_start サービスモードで実行されます
|
||||
- モジュールはインストール時に一般スクリプトを追加するべきではありません
|
||||
- モジュールスクリプト
|
||||
- モジュール独自のフォルダに配置されます
|
||||
- モジュールが有効な場合のみ実行されます
|
||||
- `post-fs-data.sh` は post-fs-data モードで実行され、`service.sh` は late_start サービスモードで実行されます
|
||||
|
||||
すべてのブートスクリプトは、KernelSU の Busybox `ash` シェルで「スタンドアロンモード」を有効にした状態で実行されます。
|
||||
@@ -1,50 +0,0 @@
|
||||
# ブートループからの復旧
|
||||
|
||||
デバイスに書き込む際、デバイスが「文鎮化」状態になる場面に遭遇することがあります。理論的には、fastboot で boot パーティションを書き込んだだけだったり、不適切なモジュールをインストールしてデバイスが起動しなくなったりした場合なら、適切な操作で復旧できます。このページでは、「文鎮化」状態になったデバイスを復旧させるための緊急手段を紹介します。
|
||||
|
||||
## boot パーティションの書き込みによる文鎮化
|
||||
|
||||
KernelSU では、以下のような状況で boot パーティションを書き込んだときに文鎮化する場合があります:
|
||||
|
||||
1. 間違った形式の boot イメージを書き込んでしまった場合。例えばお使いのデバイスのパーティション形式が `gz` なのに `lz4` 形式のイメージを書き込んでしまうと、起動しなくなります。
|
||||
2. お使いのデバイスが起動するために AVB 検証を無効にする必要がある場合(通常、無効にするにはすべてのデータを消去する必要があります)。
|
||||
3. カーネルにバグがある、または書き込みに適していない場合。
|
||||
|
||||
どのような状況であっても、**純正の boot イメージを書き込む**ことで復旧できます。したがって、インストールする前にまずは純正の boot パーティションをバックアップすることを強くおすすめします。バックアップしていない場合は、あなたと同じデバイスを持つ他のユーザー、または公式ファームウェアから純正の boot イメージを入手できます。
|
||||
|
||||
## モジュールによる文鎮化
|
||||
|
||||
モジュールのインストールはデバイスを文鎮化させる一般的な原因です。**モジュールを未知のソースからインストールしないでください**!モジュールは root 権限を持つため、あなたのデバイスに不可逆的なダメージを与える可能性があります!
|
||||
|
||||
### 通常のモジュール
|
||||
|
||||
安全であることが確認されているモジュールをインストールしてデバイスが起動しなくなった場合、KernelSU では心配することなく簡単に復旧できます。KernelSU には、以下のようなデバイスを救出するための仕組みが組み込まれています:
|
||||
|
||||
1. AB アップデート
|
||||
2. 音量下ボタンでの復旧
|
||||
|
||||
#### AB アップデート
|
||||
|
||||
KernelSU のモジュール更新は、OTA アップデートで使用される Android システムの AB アップデート機構からヒントを得ています。新しいモジュールをインストールしたり、既存のモジュールを更新したりする場合、現在使用されているモジュールファイルを直接変更することはありません。代わりに、すべてのモジュールが別のアップデートイメージに組み込まれます。システムが再起動された後、このアップデートイメージの使用を開始しようとします。Android システムが正常に起動した場合、モジュールは本当に更新されます。
|
||||
|
||||
そのため、デバイスを復旧する最もシンプルで一般的な方法は、**強制的に再起動すること**です。モジュールをインストールした後にシステムを起動できなくなった場合、電源ボタンを10秒以上長押しするとシステムが自動的に再起動します。再起動後はモジュールを更新する前の状態にロールバックされ、以前に更新したモジュールは自動的に無効化されます。
|
||||
|
||||
#### 音量下ボタンでの復旧
|
||||
|
||||
AB アップデートでも解決しない場合は、**セーフモード**を使用してみてください。セーフモードでは、すべてのモジュールが無効化されます。
|
||||
|
||||
セーフモードに入るには、2つの方法があります:
|
||||
|
||||
1. 一部のシステムの内蔵セーフモード:音量下ボタンの長押しでセーフモードに入れるシステムもあれば、リカバリーでセーフモードに入れるシステム(MIUI など)もあります。システムのセーフモードに入ると KernelSU もセーフモードに入り、自動的にモジュールを無効化します。
|
||||
2. KernelSU の内蔵セーフモード:最初の起動画面の後、**音量下キーを3回以上連続して押す**と入れます。なお、押す→離すを三回繰り返すのであって、長押しではありません。
|
||||
|
||||
セーフモードに入ると、KernelSU Manager のモジュールページにあるすべてのモジュールが無効になります。「アンインストール」操作を行うことで、問題を起こしている可能性のあるモジュールをアンインストールできます。
|
||||
|
||||
内蔵のセーフモードはカーネルに実装されているため、キーイベントを見逃す可能性はありません。ただし、GKI 以外のカーネルでは手動によるコードの統合が必要な場合があるため、公式ドキュメントを参考にしてください。
|
||||
|
||||
### 悪意のあるモジュール
|
||||
|
||||
上記の方法でデバイスを救出できない場合、インストールしたモジュールが悪意のある操作をしているか、他の手段でデバイスを損傷している可能性が高いです。この場合、2つの方法しかありません:
|
||||
|
||||
1. データを消去して純正システムをインストールし直す
|
||||
2. アフターセールスサービスに問い合わせする
|
||||
@@ -1,30 +0,0 @@
|
||||
# 非公式の対応デバイス
|
||||
|
||||
::: warning 警告
|
||||
このページでは他の開発者が管理している、KernelSU をサポートする GKI 以外のデバイス用のカーネルを紹介しています。
|
||||
:::
|
||||
|
||||
::: warning 警告
|
||||
このページはあなたのデバイスに対応するソースコードを見つけるためのものであり、そのソースコードが _KernelSU 開発者_ によってレビューされたことを意味するものではありません。ご自身の責任においてご利用ください。
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>メンテナー</th>
|
||||
<th>リポジトリ</th>
|
||||
<th>対応デバイス</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# KernelSU とは?
|
||||
|
||||
KernelSU は Android GKI デバイスのための root ソリューションです。カーネルモードで動作し、カーネル空間で直接ユーザー空間アプリに root 権限を付与します。
|
||||
|
||||
## 機能
|
||||
|
||||
KernelSU の最大の特徴は、**カーネルベース**であることです。KernelSU はカーネルモードで動作するため、今までにないカーネルインターフェイスを提供できます。例えば、カーネルモードで任意のプロセスにハードウェアブレークポイントを追加できる、誰にも気づかれずに任意のプロセスの物理メモリにアクセスできる、カーネル空間で任意のシステムコールを傍受できる、などです。
|
||||
|
||||
また、KernelSU は OverlayFS によるモジュールシステムを提供しており、カスタムプラグインをシステムに読み込めます。`/system` パーティションを変更する仕組みも提供しています。
|
||||
|
||||
## 使用方法
|
||||
|
||||
こちらをご覧ください: [インストール方法](installation)
|
||||
|
||||
## ビルド方法
|
||||
|
||||
[ビルドするには](../../guide/how-to-build)
|
||||
|
||||
## ディスカッション
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Android 向けのカーネルベース root ソリューション
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: Android 向けのカーネルベース root ソリューション
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: はじめる
|
||||
link: /ja_JP/guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: GitHub で表示
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: カーネルベース
|
||||
details: KernelSU は Linux カーネルモードで動作し、ユーザー空間よりも高度な制御が可能です。
|
||||
- title: ホワイトリストの権限管理
|
||||
details: root 権限を許可したアプリのみが su にアクセスでき、他のアプリは su を見つけられません。
|
||||
- title: モジュール対応
|
||||
details: KernelSU は OverlayFS により実際のシステムを改変せずに /system を変更できます。書き込み可能にすることさえできます。
|
||||
- title: オープンソース
|
||||
details: KernelSU は GPL-3 でライセンスされたオープンソースプロジェクトです。
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# Perfil do Aplicativo
|
||||
|
||||
O Perfil do Aplicativo é um mecanismo fornecido pelo KernelSU para personalizar a configuração de vários apps.
|
||||
|
||||
Para apps com privilégios root (ou seja, capazes de usar `su`), o Perfil do Aplicativo também pode ser chamado de Perfil root. Ele permite a customização das regras `uid`, `gid`, `grupos`, `capacidades` e `SELinux` do comando `su`, restringindo assim os privilégios do usuário root. Por exemplo, ele pode conceder permissões de rede apenas para apps de firewall enquanto nega permissões de acesso a arquivos, ou pode conceder permissões de shell em vez de acesso root completo para apps congelados: **mantendo o poder confinado com o princípio do menor privilégio.**
|
||||
|
||||
Para apps comuns sem privilégios root, o Perfil do Aplicativo pode controlar o comportamento do kernel e do sistema de módulos em relação a esses apps. Por exemplo, pode determinar se as modificações resultantes dos módulos devem ser abordadas. O kernel e o sistema de módulos podem tomar decisões com base nesta configuração, como realizar operações semelhantes a "ocultar".
|
||||
|
||||
## Perfil root
|
||||
|
||||
### UID, GID e Grupos
|
||||
|
||||
Os sistemas Linux possuem dois conceitos: usuários e grupos. Cada usuário possui um ID de usuário (UID) e pode pertencer a vários grupos, cada um com seu próprio ID de grupo (GID). Esses IDs são usados para identificar usuários no sistema e determinar quais recursos do sistema eles podem acessar.
|
||||
|
||||
Os usuários com UID 0 são conhecidos como usuários root, e grupos com GID 0 são chamados de grupos root. O grupo de usuários root geralmente tem os privilégios mais altos no sistema.
|
||||
|
||||
No caso do sistema Android, cada app funciona como um usuário separado (exceto em casos de UID compartilhado) e recebe um UID exclusivo. Por exemplo, `0` representa o usuário root, `1000` representa `system`, `2000` ao ADB shell e os UIDs de `10000` a `19999` são atribuídos a apps comuns.
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
Aqui, o UID mencionado não é o mesmo que o conceito de múltiplos usuários ou perfis de trabalho no sistema Android. Os perfis de trabalho são, na verdade, implementados particionando o intervalo UID. Por exemplo, 10000-19999 representa o usuário principal, enquanto 110000-119999 representa um perfil de trabalho. Cada app comum entre eles possui seu próprio UID exclusivo.
|
||||
:::
|
||||
|
||||
Cada app pode ter vários grupos, com o GID representando o grupo principal, que geralmente corresponde ao UID. Outros grupos são conhecidos como grupos suplementares. Certas permissões são controladas por meio de grupos, como permissões de acesso à rede ou acesso Bluetooth.
|
||||
|
||||
Por exemplo, se executarmos o comando `id` no ADB shell, a saída pode ser semelhante a esta:
|
||||
|
||||
```sh
|
||||
oriole:/ $ id
|
||||
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0
|
||||
```
|
||||
|
||||
Aqui, o UID é `2000` e o GID (ID do grupo primário) também é `2000`. Além disso, pertence a vários grupos suplementares, como `inet` (indicando a capacidade de criar soquetes `AF_INET` e `AF_INET6`) e `sdcard_rw` (indicando permissões de leitura/gravação para o cartão SD).
|
||||
|
||||
O Perfil root do KernelSU permite personalizar o UID, GID e grupos para o processo root após a execução de `su`. Por exemplo, o Perfil root de um app root pode definir seu UID como `2000`, o que significa que, ao usar `su`, as permissões reais do app estão no nível do ADB shell. Além disso, o grupo `inet` pode ser removido, evitando que o comando `su` tenha acesso à rede.
|
||||
|
||||
::: tip OBSERVAÇÃO
|
||||
O Perfil do Aplicativo controla apenas as permissões do processo root após usar `su` e não afeta as permissões do próprio app. Se um app solicitou permissão para acessar a rede, ele ainda poderá acessar a rede mesmo sem usar `su`. Remover o grupo `inet` de `su` apenas impede que `su` acesse a rede.
|
||||
:::
|
||||
|
||||
O Perfil root é aplicado no kernel e não depende do comportamento voluntário de apps root, ao contrário da troca de usuários ou grupos por meio de `su`. A concessão da permissão `su` depende inteiramente do usuário e não do desenvolvedor.
|
||||
|
||||
### Capacidades
|
||||
|
||||
As capacidades são um mecanismo para separação de privilégios no Linux.
|
||||
|
||||
Para realizar verificações de permissão, as implementações tradicionais do `UNIX` distinguem duas categorias de processos: processos privilegiados (cujo ID de usuário efetivo é `0`, referido como superusuário ou root) e processos sem privilégios (cujo UID efetivo é diferente de zero). Os processos privilegiados ignoram todas as verificações de permissão do kernel, enquanto os processos não privilegiados estão sujeitos à verificação completa de permissão com base nas credenciais do processo (geralmente: UID efetivo, GID efetivo e lista de grupos suplementares).
|
||||
|
||||
A partir do Linux 2.2, o Linux divide os privilégios tradicionalmente associados ao superusuário em unidades distintas, conhecidas como capacidades, que podem ser ativadas e desativadas de forma independente.
|
||||
|
||||
Cada capacidade representa um ou mais privilégios. Por exemplo, `CAP_DAC_READ_SEARCH` representa a capacidade de ignorar verificações de permissão para leitura de arquivos, bem como permissões de leitura e execução de diretório. Se um usuário com um UID efetivo `0` (usuário root) não tiver a capacidade `CAP_DAC_READ_SEARCH` ou superiores, isso significa que mesmo sendo root, ele não pode ler arquivos à vontade.
|
||||
|
||||
O Perfil root do KernelSU permite a personalização das capacidades do processo root após a execução de `su`, concedendo assim "privilégios root" de forma parcial. Ao contrário do UID e GID mencionados acima, certos apps root exigem um UID de `0` após usar `su`. Nesses casos, limitar as capacidades deste usuário root com UID `0` pode restringir as operações que ele pode realizar.
|
||||
|
||||
::: tip FORTE RECOMENDAÇÃO
|
||||
A [documentação oficial](https://man7.org/linux/man-pages/man7/capabilities.7.html) da capacidade do Linux fornece explicações detalhadas das habilidades representadas por cada capacidade. Se você pretende customizar as capacidade, é altamente recomendável que você leia este documento primeiro.
|
||||
:::
|
||||
|
||||
### SELinux
|
||||
|
||||
SELinux é um poderoso mecanismo do Controle de Acesso Obrigatório (MAC). Ele opera com base no princípio de **negação padrão**. Qualquer ação não explicitamente permitida é negada.
|
||||
|
||||
O SELinux pode ser executado em dois modos globais:
|
||||
|
||||
1. Modo permissivo: Os eventos de negação são registrados, mas não aplicados.
|
||||
2. Modo de aplicação: Os eventos de negação são registrados e aplicados.
|
||||
|
||||
::: warning AVISO
|
||||
Os sistemas Android modernos dependem fortemente do SELinux para garantir a segurança geral do sistema. É altamente recomendável não usar nenhum sistema personalizado executado em "Modo permissivo", pois ele não oferece vantagens significativas em relação a um sistema completamente aberto.
|
||||
:::
|
||||
|
||||
Explicar o conceito completo do SELinux é complexo e está além do objetivo deste documento. Recomenda-se primeiro entender seu funcionamento através dos seguintes recursos:
|
||||
|
||||
1. [Wikipédia](https://en.wikipedia.org/wiki/Security-Enhanced_Linux)
|
||||
2. [Red Hat: O que é SELinux?](https://www.redhat.com/pt-br/topics/linux/what-is-selinux)
|
||||
3. [ArchLinux: SELinux](https://wiki.archlinux.org/title/SELinux)
|
||||
|
||||
O Perfil root do KernelSU permite a personalização do contexto SELinux do processo root após a execução de `su`. Regras específicas de controle de acesso podem ser definidas para este contexto, possibilitando um controle refinado sobre os privilégios root.
|
||||
|
||||
Em cenários típicos, quando um app executa `su`, ele alterna o processo para um domínio SELinux com **acesso irrestrito**, como `u:r:su:s0`. Através do Perfil root, esse domínio pode ser mudado para um domínio personalizado, como `u:r:app1:s0`, e uma série de regras podem ser definidas para esse domínio:
|
||||
|
||||
```sh
|
||||
type app1
|
||||
enforce app1
|
||||
typeattribute app1 mlstrustedsubject
|
||||
allow app1 * * *
|
||||
```
|
||||
|
||||
Observe que a regra `allow app1 * * *` é usada apenas para fins de demonstração. Na prática, esta regra não deve ser utilizada extensivamente, pois não difere muito do Modo permissivo.
|
||||
|
||||
### Escalação
|
||||
|
||||
Se a configuração do Perfil root não estiver definida corretamente, poderá ocorrer um cenário de escalação. As restrições impostas pelo Perfil root poderão falhar involuntariamente.
|
||||
|
||||
Por exemplo, se você conceder permissão root a um usuário ADB shell (que é um caso comum) e, em seguida, conceder permissão root a um app normal, mas configurar seu Perfil root com o UID 2000 (o UID do usuário ADB shell), o app pode obter acesso root completo ao executar o comando `su` duas vezes:
|
||||
|
||||
1. A primeira execução de `su` será sujeita ao Perfil do Aplicativo, e mudará para o UID `2000` (ADB shell) em vez de `0` (root).
|
||||
2. A segunda execução de `su`, como o UID é `2000` e você concedeu acesso root ao UID `2000` (ADB shell) na configuração, o app obterá privilégios root completo.
|
||||
|
||||
::: warning OBSERVAÇÃO
|
||||
Este comportamento é totalmente esperado e não é um bug. Portanto, recomendamos o seguinte:
|
||||
|
||||
Se você realmente precisa conceder privilégios root ao ADB (por exemplo, como desenvolvedor), não é aconselhável alterar o UID para `2000` ao configurar o Perfil root. Usar `1000` (system) seria uma melhor escolha.
|
||||
:::
|
||||
|
||||
## Perfil não root
|
||||
|
||||
### Desmontar módulos
|
||||
|
||||
O KernelSU fornece um mecanismo sem sistema para modificar partições do sistema, obtido através da montagem do OverlayFS. No entanto, alguns apps podem ser sensíveis a esse comportamento. Nesse caso, podemos descarregar módulos montados nesses apps configurando a opção "Desmontar módulos".
|
||||
|
||||
Além disso, a interface de configurações do gerenciador do KernelSU oferece a opção "Desmontar módulos por padrão". Por padrão, essa opção está **ativada**, o que significa que o KernelSU ou alguns módulos descarregarão módulos para este app, a menos que configurações adicionais sejam aplicadas. Se você não preferir esta configuração ou se ela afetar determinados apps, você terá as seguintes opções:
|
||||
|
||||
1. Manter a opção "Desmontar módulos por padrão" ativada e desative individualmente a opção "Desmontar módulos" no Perfil do Aplicativo para apps que exigem o carregamento do módulo (agindo como uma "lista de permissões").
|
||||
2. Desativar a opção "Desmontar módulos por padrão" e ativar individualmente a opção "Desmontar módulos" no Perfil do Aplicativo para apps que exigem o descarregamento do módulo (agindo como uma "lista negra").
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
Em dispositivos que utilizam a versão do kernel 5.10 ou superior, o kernel realiza qualquer ação adicional do descarregamento de módulos. No entanto, para dispositivos que executam versões do kernel abaixo de 5.10, essa opção é apenas uma opção de configuração e o próprio KernelSU não executa nenhuma ação. Se você quiser usar a opção "Desmontar módulos" em versões do kernel anteriores a 5.10, é necessário portar a função `path_umount` em `fs/namespace.c`. Você pode obter mais informações no final da página [Integração para dispositivos não-GKI](https://kernelsu.org/pt_BR/guide/how-to-integrate-for-non-gki.html). Alguns módulos, como ZygiskNext, também podem usar essa opção para determinar se o descarregamento do módulo é necessário.
|
||||
:::
|
||||
@@ -1,28 +0,0 @@
|
||||
# Diferenças com Magisk
|
||||
|
||||
Embora os módulos do KernelSU e do Magisk tenham muitas semelhanças, existem inevitavelmente algumas diferenças devido aos seus mecanismos de implementação completamente diferentes. Se você deseja que seu módulo funcione tanto no Magisk quanto no KernelSU, é essencial compreender essas diferenças.
|
||||
|
||||
## Semelhanças
|
||||
|
||||
- Formato de arquivo do módulo: Ambos usam o formato ZIP para organizar os módulos, e o formato dos módulos é praticamente o mesmo.
|
||||
- Diretório de instalação do módulo: Ambos estão localizados em `/data/adb/modules`.
|
||||
- Sem sistema: Ambos suportam a modificação de `/system` de forma sem sistema por meio de módulos.
|
||||
- post-fs-data.sh: O tempo de execução e a semântica são exatamente os mesmos.
|
||||
- service.sh: O tempo de execução e a semântica são exatamente os mesmos.
|
||||
- system.prop: Completamente o mesmo.
|
||||
- sepolicy.rule: Completamente o mesmo.
|
||||
- BusyBox: Os scripts são executados no BusyBox com o "Modo Autônomo" ativado em ambos os casos.
|
||||
|
||||
## Diferenças
|
||||
|
||||
Antes de entender as diferenças, é importante saber como identificar se o seu módulo está sendo executado no KernelSU ou no Magisk. Você pode usar a variável de ambiente `KSU` para diferenciá-lo em todos os locais onde você pode executar os scripts do módulo (`customize.sh`, `post-fs-data.sh`, `service.sh`). No KernelSU, essa variável de ambiente será definida como `true`.
|
||||
|
||||
Aqui estão algumas diferenças:
|
||||
|
||||
- Os módulos KernelSU não podem ser instalados no modo Recovery.
|
||||
- Os módulos KernelSU não oferece suporte nativo ao Zygisk, mas você pode usar módulos Zygisk através do [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
- O método para substituir ou excluir arquivos nos módulos do KernelSU é completamente diferente do Magisk. O KernelSU não suporta o método `.replace`. Em vez disso, você deve criar um arquivo com o comando `mknod filename c 0 0` para excluir o arquivo correspondente.
|
||||
- Os diretórios do BusyBox são diferentes. O BusyBox integrado no KernelSU está localizado em `/data/adb/ksu/bin/busybox`, enquanto no Magisk está em `/data/adb/magisk/busybox`. **Observe que este é um comportamento interno do KernelSU e pode mudar no futuro!**
|
||||
- O KernelSU não suporta arquivos `.replace`, mas oferece suporte às variáveis `REMOVE` e `REPLACE` para remover ou substituir arquivos e pastas.
|
||||
- O KernelSU adiciona o estágio `boot-completed` para executar scripts após a inicialização ser concluída.
|
||||
- O KernelSU adiciona o estágio `post-mount` para executar scripts após o OverlayFS ser montado.
|
||||
@@ -1,78 +0,0 @@
|
||||
# Perguntas frequentes
|
||||
|
||||
## KernelSU oferece suporte ao meu dispositivo?
|
||||
|
||||
Primeiro, seu dispositivo deve ser capaz de desbloquear o bootloader. Se não, então não há suporte.
|
||||
|
||||
Em seguida, instale o gerenciador do KernelSU no seu dispositivo e abra-o. Se aparecer `Sem suporte` então seu dispositivo não pode ser suportado imediatamente. No entanto, você pode compilar a fonte do kernel e integrar o KernelSU para fazê-lo funcionar ou usar [Dispositivos com suporte não oficial](unofficially-support-devices).
|
||||
|
||||
## Para usar o KernelSU precisa desbloquear o bootloader?
|
||||
|
||||
Certamente, sim.
|
||||
|
||||
## KernelSU suporta módulos?
|
||||
|
||||
Sim, verifique [Guias de módulo](module.md).
|
||||
|
||||
## KernelSU suporta Xposed?
|
||||
|
||||
Sim, você pode usar LSPosed com [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## KernelSU suporta Zygisk?
|
||||
|
||||
KernelSU não tem suporte integrado ao Zygisk, mas você pode usar [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## KernelSU é compatível com o Magisk?
|
||||
|
||||
O sistema de módulos do KernelSU está em conflito com a montagem mágica do Magisk. Se houver algum módulo ativado no KernelSU, todo o Magisk deixará de funcionar.
|
||||
|
||||
No entanto, se você usar apenas o `su` do KernelSU, ele funcionará bem com o Magisk. O KernelSU modifica o `kernel`, enquanto o Magisk modifica o `ramdisk`, permitindo que ambos trabalhem juntos.
|
||||
|
||||
## KernelSU substituirá o Magisk?
|
||||
|
||||
Acreditamos que não, e esse não é o nosso objetivo. O Magisk é bom o suficiente para solução root do espaço do usuário e terá uma longa vida. O objetivo do KernelSU é fornecer uma interface de kernel aos usuários, não substituindo o Magisk.
|
||||
|
||||
## KernelSU oferece suporte a dispositivos não-GKI?
|
||||
|
||||
É possível. Mas você deve baixar o código-fonte do kernel e integrar o KernelSU à árvore do código-fonte e compilar o kernel você mesmo.
|
||||
|
||||
## KernelSU oferece suporte a dispositivos abaixo do Android 12?
|
||||
|
||||
É o kernel do dispositivo que afeta a compatibilidade do KernelSU e não tem nada a ver com a versão do Android. A única restrição é que os dispositivos lançados com Android 12 devem ser kernel 5.10+ (dispositivos GKI). Então:
|
||||
|
||||
1. Os dispositivos lançados com Android 12 devem ser compatíveis.
|
||||
2. Dispositivos com kernel antigo (alguns dispositivos com Android 12 também têm o kernel antigo) são compatíveis (você mesmo deve compilar o kernel).
|
||||
|
||||
## KernelSU suporta kernel antigo?
|
||||
|
||||
É possível, o KernelSU é portado para o kernel 4.14 agora. Para kernels mais antigo, você precisa portar manualmente e PRs são sempre bem-vindas!
|
||||
|
||||
## Como integrar o KernelSU para um kernel antigo?
|
||||
|
||||
Por favor, verifique o guia [Integração para dispositivos não-GKI](how-to-integrate-for-non-gki).
|
||||
|
||||
## Por que a minha versão do Android é 13 e o kernel mostra "android12-5.10"?
|
||||
|
||||
A versão do Kernel não tem nada a ver com a versão do Android. Se você precisar fazer o flash do kernel, use sempre a versão do kernel, a versão do Android não é tão importante.
|
||||
|
||||
## Eu sou GKI 1.0, posso usar isso?
|
||||
|
||||
GKI 1.0 é completamente diferente do GKI 2.0, você deve compilar o kernel sozinho.
|
||||
|
||||
## Como posso fazer `/system` RW?
|
||||
|
||||
Não recomendamos que você modifique a partição do sistema diretamente. Por favor, verifique [Guias de módulo](module.md) para modificá-lo sem sistema. Se você insiste em fazer isso, verifique [magisk_overlayfs](https://github.com/HuskyDG/magic_overlayfs).
|
||||
|
||||
## KernelSU pode modificar hosts? Como posso usar AdAway?
|
||||
|
||||
Claro. Mas o KernelSU não tem suporte a hosts integrados, você pode instalar [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) para fazer isso.
|
||||
|
||||
## Por que existe um enorme arquivo de 1 TB?
|
||||
|
||||
O arquivo `modules.img` de 1 TB é um arquivo de imagem de disco. **Não se preocupe com seu tamanho**; ele é um tipo especial de arquivo conhecido como [arquivo esparso](https://en.wikipedia.org/wiki/Sparse_file). Seu tamanho real é apenas o tamanho do módulo que você usa e diminuirá dinamicamente após a exclusão do módulo. Na verdade, ele não ocupa 1 TB de espaço em disco (seu celular pode não ter tanto espaço).
|
||||
|
||||
Se você realmente se incomodar com o tamanho desse arquivo, você pode usar o comando `resize2fs -M` para ajustá-lo ao tamanho real. Porém, o módulo pode não funcionar corretamente nesse caso, e não forneceremos suporte para isso.
|
||||
|
||||
## Por que meu dispositivo mostra o tamanho de armazenamento errado?
|
||||
|
||||
Certos dispositivos usam métodos não padrão para calcular o tamanho de armazenamento do dispositivo, o que pode levar a cálculos imprecisos nos apps e menus do sistema, especialmente ao lidar com arquivos esparsos de 1 TB. Embora esse problema pareça ser específico para os dispositivos Samsung, afetando principalmente os apps e serviços da Samsung, é importante observar que a discrepância está principalmente no tamanho total do armazenamento, enquanto o cálculo do espaço livre permanece preciso.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Recursos ocultos
|
||||
|
||||
## .ksurc
|
||||
|
||||
Por padrão, `/system/bin/sh` carrega `/system/etc/mkshrc`.
|
||||
|
||||
Você pode fazer su carregar um arquivo rc personalizado criando um arquivo `/data/adb/ksu/.ksurc`.
|
||||
@@ -1,71 +0,0 @@
|
||||
# Como compilar
|
||||
|
||||
Primeiro, você deve ler a documentação oficial do Android para compilação do kernel:
|
||||
|
||||
1. [Como criar kernels](https://source.android.com/docs/setup/build/building-kernels)
|
||||
2. [Builds de versão de imagem genérica do kernel (GKI)](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
::: warning AVISO
|
||||
Esta página é para dispositivos GKI, se você usa um kernel antigo, consulte [Integração para dispositivos não-GKI](how-to-integrate-for-non-gki).
|
||||
:::
|
||||
|
||||
## Compilar o kernel
|
||||
|
||||
### Sincronize o código-fonte do kernel
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
O arquivo `<kernel_manifest.xml>` é um manifesto que pode determinar exclusivamente uma compilação, permitindo que você a torne reprodutível. Para isso, você deve baixar o arquivo de manifesto em [Builds de versão de imagem genérica do kernel (GKI)](https://source.android.com/docs/core/architecture/kernel/gki-release-builds).
|
||||
|
||||
### Construir
|
||||
|
||||
Por favor, verifique [Como criar kernels](https://source.android.com/docs/setup/build/building-kernels) primeiro.
|
||||
|
||||
Por exemplo, para compilar uma imagem de kernel `aarch64`:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Não se esqueça de adicionar o sinalizador `LTO=thin`, caso contrário a compilação poderá falhar se a memória do seu computador for inferior a 24 GB.
|
||||
|
||||
A partir do Android 13, o kernel é compilado pelo `bazel`:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
Para alguns kernel do Android 14, para fazer o Wi-Fi/Bluetooth funcionar, pode ser necessário remover todas as exportações protegidas pelo GKI:
|
||||
|
||||
```sh
|
||||
rm common/android/abi_gki_protected_exports_*
|
||||
```
|
||||
:::
|
||||
|
||||
## Compilar o kernel com KernelSU
|
||||
|
||||
Se você conseguir compilar o kernel com sucesso, adicionar suporte ao KernelSU será relativamente simples. Na raiz do diretório de origem do kernel, execute qualquer uma das opções listadas abaixo:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh[Tag mais recente (estável)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
```sh[Branch principal (dev)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
```sh[Selecionar tag (como v0.5.2)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Então, reconstrua o kernel e você obterá uma imagem do kernel com o KernelSU!
|
||||
@@ -1,377 +0,0 @@
|
||||
# Integração para dispositivos não-GKI
|
||||
|
||||
O KernelSU pode ser integrado a kernels não-GKI e foi portado para 4.14 e versões anteriores.
|
||||
|
||||
Devido à fragmentação dos kernels não-GKI, não temos um método universal para construí-lo, portanto, não podemos fornecer o boot.img não-GKI. No entanto, você pode compilar o kernel com o KernelSU integrado por conta própria.
|
||||
|
||||
Primeiro, você deve ser capaz de compilar um kernel inicializável a partir do código-fonte do kernel. Se o kernel não for de código aberto, será difícil executar o KernelSU para o seu dispositivo.
|
||||
|
||||
Se você puder compilar um kernel inicializável, existem duas maneiras de integrar o KernelSU ao código-fonte do kernel:
|
||||
|
||||
1. Automaticamente com `kprobe`
|
||||
2. Manualmente
|
||||
|
||||
## Integrar com kprobe
|
||||
|
||||
O KernelSU usa kprobe para fazer ganchos do kernel, se o kprobe funcionar bem em seu kernel, é recomendado usar desta forma.
|
||||
|
||||
Primeiro, adicione o KernelSU à árvore de origem do kernel:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
[KernelSU 1.0 e versões posteriores não suportam mais kernels não-GKI](https://github.com/tiann/KernelSU/issues/1705). A última versão suportada é a `v0.9.5`, portanto, certifique-se de usar a versão correta.
|
||||
:::
|
||||
|
||||
Então, você deve verificar se o kprobe está ativado na configuração do seu kernel. Caso não esteja, adicione estas configurações a ele:
|
||||
|
||||
```txt
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
Agora, ao recompilar seu kernel, o KernelSU deve funcionar corretamente.
|
||||
|
||||
Se você descobrir que o KPROBES ainda não está ativado, pode tentar ativar `CONFIG_MODULES`. Se isso não resolver, use `make menuconfig` para procurar outras dependências do KPROBES.
|
||||
|
||||
Porém, se você entrar em um bootloop após integrar o KernelSU, isso pode indicar que o **kprobe está quebrado no seu kernel**, o que significa que você precisará corrigir o bug do kprobe ou usar outra maneira.
|
||||
|
||||
::: tip COMO VERIFICAR SE O KPROBE ESTÁ QUEBRADO?
|
||||
Comente `ksu_enable_sucompat()` e `ksu_enable_ksud()` em `KernelSU/kernel/ksu.c`, se o dispositivo inicializar normalmente, então o kprobe pode estar quebrado.
|
||||
:::
|
||||
|
||||
::: info COMO FAZER COM QUE O RECURSO DE DESMONTAR MÓDULOS FUNCIONE NO PRÉ-GKI?
|
||||
Se o seu kernel for inferior a 5.9, você deve portar `path_umount` para `fs/namespace.c`. Isso é necessário para que o recurso "Desmontar módulos" funcione corretamente. Caso você não porte `path_umount`, o recurso "Desmontar módulos" não funcionará. Você pode obter mais informações sobre como conseguir isso no final desta página.
|
||||
:::
|
||||
|
||||
## Modifique manualmente a fonte do kernel
|
||||
|
||||
Se o kprobe não funcionar no seu kernel (isso pode ser causado por um bug no upstream ou do kernel abaixo de 4.8), então você pode tentar o seguinte:
|
||||
|
||||
Primeiro, adicione o KernelSU à árvore de origem do kernel:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5
|
||||
```
|
||||
|
||||
Tenha em mente que, em alguns dispositivos, seu defconfig pode estar localizado em `arch/arm64/configs` ou em outros casos pode estar em `arch/arm64/configs/vendor/your_defconfig`. Independentemente do defconfig que você estiver usando, certifique-se de ativar `CONFIG_KSU` com `y` para ativa-lo ou `n` para desativa-lo. Por exemplo, se optar por ativá-lo, seu defconfig deverá conter a seguinte linha:
|
||||
|
||||
```txt
|
||||
# KernelSU
|
||||
CONFIG_KSU=y
|
||||
```
|
||||
|
||||
Em seguida, adicione chamadas do KernelSU à fonte do kernel. Abaixo estão alguns patches para referência:
|
||||
|
||||
::: code-group
|
||||
|
||||
```diff[exec.c]
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
+#endif
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ #endif
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff[open.c]
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
/*
|
||||
* access() precisa usar o uid/gid real, não o uid/gid efetivo.
|
||||
* Fazemos isso limpando temporariamente todos os recursos relacionados ao FS e
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff[read_write.c]
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
+#endif
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+ #endif
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff[stat.c]
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Obtenha atributos básicos e extras por filename
|
||||
* @dfd: Um descritor de arquivo que representa o diretório base para um filename relativo
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
+ #endif
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Você deve encontrar as quatro funções no código-fonte do kernel:
|
||||
|
||||
1. `do_faccessat`, geralmente em `fs/open.c`
|
||||
2. `do_execveat_common`, geralmente em `fs/exec.c`
|
||||
3. `vfs_read`, geralmente em `fs/read_write.c`
|
||||
4. `vfs_statx`, geralmente em `fs/stat.c`
|
||||
|
||||
Se o seu kernel não tiver a função `vfs_statx`, use `vfs_fstatat`:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fstat);
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+#endif
|
||||
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int flag)
|
||||
{
|
||||
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = 0;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||
+ #endif
|
||||
+
|
||||
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH)) != 0)
|
||||
goto out;
|
||||
```
|
||||
|
||||
Para kernels anteriores ao 4.17, se você não conseguir encontrar `do_faccessat`, basta ir até a definição do syscall `faccessat` e fazer a chamada lá:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 2ff887661237..e758d7db7663 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return error;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* access() precisa usar o uid/gid real, não o uid/gid efetivo.
|
||||
* Fazemos isso limpando temporariamente todos os recursos relacionados ao FS e
|
||||
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+ #endif
|
||||
+
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
### Modo de Segurança
|
||||
|
||||
Para ativar o Modo de Segurança integrado do KernelSU, você deve modificar a função `input_handle_event` em `drivers/input/input.c`:
|
||||
|
||||
::: tip DICA
|
||||
É altamente recomendável ativar este recurso, é muito útil para evitar bootloops!
|
||||
:::
|
||||
|
||||
```diff
|
||||
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
||||
index 45306f9ef247..815091ebfca4 100755
|
||||
--- a/drivers/input/input.c
|
||||
+++ b/drivers/input/input.c
|
||||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev,
|
||||
return disposition;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern bool ksu_input_hook __read_mostly;
|
||||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);
|
||||
+#endif
|
||||
+
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition = input_get_disposition(dev, type, code, &value);
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ if (unlikely(ksu_input_hook))
|
||||
+ ksu_handle_input_handle_event(&type, &code, &value);
|
||||
+ #endif
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
::: info ENTRANDO NO MODO DE SEGURANÇA ACIDENTALMENTE?
|
||||
Se você estiver usando a integração manual e não desativar `CONFIG_KPROBES`, o usuário poderá acionar o Modo de Segurança pressionando o botão de diminuir volume após a inicialização! Portanto, se estiver usando a integração manual, é necessário desativar `CONFIG_KPROBES`!
|
||||
:::
|
||||
|
||||
### Falha ao executar `pm` no terminal?
|
||||
|
||||
Você deve modificar `fs/devpts/inode.c`. Referência:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
|
||||
index 32f6f1c68..d69d8eca2 100644
|
||||
--- a/fs/devpts/inode.c
|
||||
+++ b/fs/devpts/inode.c
|
||||
@@ -602,6 +602,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
return dentry;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KSU
|
||||
+extern int ksu_handle_devpts(struct inode*);
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* devpts_get_priv -- get private data for a slave
|
||||
* @pts_inode: inode of the slave
|
||||
@@ -610,6 +612,7 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||
*/
|
||||
void *devpts_get_priv(struct dentry *dentry)
|
||||
{
|
||||
+ #ifdef CONFIG_KSU
|
||||
+ ksu_handle_devpts(dentry->d_inode);
|
||||
+ #ifdef CONFIG_KSU
|
||||
if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC)
|
||||
return NULL;
|
||||
return dentry->d_fsdata;
|
||||
```
|
||||
|
||||
### Como portar path_umount
|
||||
|
||||
Você pode fazer com que o recurso "Desmontar módulos" funcione em kernels pré-GKI portando manualmente `path_umount` da versão 5.9. Você pode usar este patch como referência:
|
||||
|
||||
```diff
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1739,6 +1739,39 @@ static inline bool may_mandlock(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
+static int can_umount(const struct path *path, int flags)
|
||||
+{
|
||||
+ struct mount *mnt = real_mount(path->mnt);
|
||||
+
|
||||
+ if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
|
||||
+ return -EINVAL;
|
||||
+ if (!may_mount())
|
||||
+ return -EPERM;
|
||||
+ if (path->dentry != path->mnt->mnt_root)
|
||||
+ return -EINVAL;
|
||||
+ if (!check_mnt(mnt))
|
||||
+ return -EINVAL;
|
||||
+ if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
|
||||
+ return -EINVAL;
|
||||
+ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
|
||||
+ return -EPERM;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int path_umount(struct path *path, int flags)
|
||||
+{
|
||||
+ struct mount *mnt = real_mount(path->mnt);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = can_umount(path, flags);
|
||||
+ if (!ret)
|
||||
+ ret = do_umount(mnt, flags);
|
||||
+
|
||||
+ /* não devemos chamar path_put() pois isso limparia mnt_expiry_mark */
|
||||
+ dput(path->dentry);
|
||||
+ mntput_no_expire(mnt);
|
||||
+ return ret;
|
||||
+}
|
||||
/*
|
||||
* Agora o umount pode lidar com pontos de montagem e também com dispositivos bloqueados.
|
||||
* Isto é importante para filesystems que usam dispositivos bloqueados sem nome.
|
||||
```
|
||||
|
||||
Finalmente, compile seu kernel novamente e o KernelSU deverá funcionar corretamente.
|
||||
@@ -1,280 +0,0 @@
|
||||
# Instalação
|
||||
|
||||
## Verifique se o seu dispositivo é compatível
|
||||
|
||||
Baixe o gerenciador do KernelSU em [GitHub Releases](https://github.com/tiann/KernelSU/releases) e instale-o no seu dispositivo:
|
||||
|
||||
- Se o app mostrar `Sem suporte`, significa que **você precisará compilar o kernel por conta própria**. O KernelSU não fornecerá e nunca fornecerá um arquivo boot.img para você instalar.
|
||||
- Se o app mostrar `Não instalado`, então seu dispositivo é oficialmente suportado pelo KernelSU.
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
Para dispositivos que mostram `Sem suporte`, você pode conferir a lista de [Dispositivos com suporte não oficial](unofficially-support-devices.md). Você mesmo pode compilar o kernel.
|
||||
:::
|
||||
|
||||
## Backup padrão do boot.img
|
||||
|
||||
Antes de fazer o flash, é essencial que você faça o backup do seu boot.img padrão. Se encontrar algum bootloop, você sempre pode restaurar o sistema voltando ao boot padrão de fábrica usando o fastboot.
|
||||
|
||||
::: warning AVISO
|
||||
O flash pode causar perda de dados. Certifique-se de executar esta etapa bem antes de prosseguir para a próxima! Se necessário, também é recomendável fazer backup de todos os dados do seu dispositivo.
|
||||
:::
|
||||
|
||||
## Conhecimento necessário
|
||||
|
||||
### ADB e fastboot
|
||||
|
||||
Por padrão, você usará as ferramentas ADB e fastboot neste tutorial, portanto, se você não as conhece, recomendamos pesquisar para aprender sobre elas primeiro.
|
||||
|
||||
### KMI
|
||||
|
||||
Kernel Module Interface (KMI), versões de kernel com o mesmo KMI são **compatíveis**, isso é o que "geral" significa no GKI. Por outro lado, se o KMI for diferente, então esses kernels não são compatíveis entre si, e atualizar uma imagem do kernel com um KMI diferente do seu dispositivo pode causar um bootloop.
|
||||
|
||||
Especificamente, para dispositivos GKI, o formato da versão do kernel deve ser a seguinte:
|
||||
|
||||
```txt
|
||||
KernelRelease :=
|
||||
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
|
||||
w .x .y -zzz -k -alguma coisa
|
||||
```
|
||||
|
||||
`w.x-zzz-k` é a versão KMI. Por exemplo, se a versão do kernel de um dispositivo for `5.10.101-android12-9-g30979850fc20`, então seu KMI será `5.10-android12-9`. Teoricamente, ele pode inicializar normalmente com outros kernels KMI.
|
||||
|
||||
::: tip DICA
|
||||
Observe que o SubLevel na versão do kernel não faz parte do KMI! Isso significa que `5.10.101-android12-9-g30979850fc20` tem o mesmo KMI que `5.10.137-android12-9-g30979850fc20`!
|
||||
:::
|
||||
|
||||
### Nível do patch de segurança {#security-patch-level}
|
||||
|
||||
Dispositivos Android mais recentes podem ter mecanismos anti-rollback que impedem o flash de um boot.img com um nível de patch de segurança antigo. Por exemplo, se o kernel do seu dispositivo for `5.10.101-android12-9-g30979850fc20`, o patch de segurança será `2023-11`, mesmo se você atualizar o kernel correspondente ao KMI do kernel, se o nível do patch de segurança for anterior a `2023-11` (como `2023-06`), isso pode causar um bootloop.
|
||||
|
||||
Portanto, kernels com os níveis de patch de segurança mais recentes são preferidos para manter a compatibilidade com o KMI.
|
||||
|
||||
### Versão do kernel vs Versão do Android
|
||||
|
||||
Por favor, observe: **A versão do kernel e a versão do Android não são necessariamente iguais!**
|
||||
|
||||
Se você descobrir que a versão do seu kernel é `android12-5.10.101`, mas a versão do seu sistema Android é Android 13 ou outra, não se surpreenda, pois o número da versão do sistema Android não é necessariamente igual ao número da versão do kernel Linux. O número da versão do kernel Linux geralmente é correspondente à versão do sistema Android que acompanha o **dispositivo quando ele é enviado**. Se o sistema Android for atualizado posteriormente, a versão do kernel geralmente não será alterada. Então, antes de flashar qualquer coisa, **consulte sempre a versão do kernel!**
|
||||
|
||||
## Introdução
|
||||
|
||||
Desde a versão [0.9.0](https://github.com/tiann/KernelSU/releases/tag/v0.9.0), o KernelSU suporta dois modos de execução em dispositivos GKI:
|
||||
|
||||
1. `GKI`: Substitue o kernel original do dispositivo pelo **Generic Kernel Image** (GKI) fornecido pelo KernelSU.
|
||||
2. `LKM`: Carregue o **Loadable Kernel Module** (LKM) no kernel do dispositivo sem substituir o kernel original.
|
||||
|
||||
Esses dois modos são adequados para diferentes cenários, e você pode escolher o mais adequado conforme suas necessidades.
|
||||
|
||||
### Modo GKI {#gki-mode}
|
||||
|
||||
No modo GKI, o kernel original do dispositivo será substituído pela imagem genérica do kernel fornecida pelo KernelSU. As vantagens do modo GKI são:
|
||||
|
||||
1. Forte universalidade, adequada para a maioria dos dispositivos. Por exemplo, a Samsung ativou dispositivos KNOX, e o modo LKM não pode funcionar. Existem também alguns dispositivos modificados de nicho que só podem usar o modo GKI.
|
||||
2. Pode ser usado sem depender de firmware oficial, e não há necessidade de esperar por atualizações oficiais de firmware, desde que o KMI seja consistente, ele pode ser usado.
|
||||
|
||||
### Modo LKM {#lkm-mode}
|
||||
|
||||
No modo LKM, o kernel original do dispositivo não será substituído, mas o módulo do kernel carregável será carregado no kernel do dispositivo. As vantagens do modo LKM são:
|
||||
|
||||
1. Não substituirá o kernel original do dispositivo. Se você tiver os requisitos especiais para o kernel original do dispositivo ou quiser usar o KernelSU enquanto usa um kernel de terceiros, poderá usar o modo LKM.
|
||||
2. É mais conveniente atualizar o OTA. Ao atualizar o KernelSU, você pode instalá-lo diretamente no gerenciador sem flashar manualmente. Após o sistema OTA, você pode instalá-lo diretamente no segundo slot sem flashar manualmente.
|
||||
3. Adequado para alguns cenários especiais. Por exemplo, o LKM também pode ser carregado com privilégios root temporários. Como não é necessário substituir a partição boot, ele não acionará o AVB e não causará o bloqueio do dispositivo.
|
||||
4. O LKM pode ser desinstalado temporariamente. Se você deseja desativar temporariamente o acesso root, você pode desinstalar o LKM. Este processo não requer o flash de partições, nem mesmo a reinicialização do dispositivo. Se quiser ativar o root novamente, basta reiniciar o dispositivo.
|
||||
|
||||
::: tip COEXISTÊNCIA DE DOIS MODOS
|
||||
Após abrir o gerenciador, você pode ver o modo atual do dispositivo na página inicial. Observe que a prioridade do modo GKI é maior que a do LKM. Por exemplo, se você usar o kernel GKI para substituir o kernel original e usar LKM para corrigir o kernel GKI, o LKM será ignorado e o dispositivo sempre será executado no modo GKI.
|
||||
:::
|
||||
|
||||
### Qual escolher? {#which-one}
|
||||
|
||||
Se o seu aparelho for um celular, recomendamos que você priorize o modo LKM. Se o seu dispositivo for um emulador, WSA ou Waydroid, recomendamos que você priorize o modo GKI.
|
||||
|
||||
## Instalação do LKM
|
||||
|
||||
### Obtenha o firmware oficial
|
||||
|
||||
Para usar o modo LKM, você precisa obter o firmware oficial e corrigi-lo com base no firmware oficial. Se você usar um kernel de terceiros, poderá usar o `boot.img` do kernel de terceiros como firmware oficial.
|
||||
|
||||
Existem muitas maneiras de obter o firmware oficial. Se o seu dispositivo suportar `fastboot boot`, então recomendamos **o método mais simples e indicado**, que consiste em usar `fastboot boot` para inicializar temporariamente o kernel GKI fornecido pelo KernelSU, depois instalar o gerenciador e, finalmente, instalá-lo diretamente pelo gerenciador. Este método não exige o download manual do firmware oficial nem a extração manual do boot.
|
||||
|
||||
Se o seu dispositivo não suportar `fastboot boot`, pode ser necessário baixar manualmente o pacote de firmware oficial e extrair o boot dele.
|
||||
|
||||
Ao contrário do modo GKI, o modo LKM modifica o `ramdisk`. Portanto, em dispositivos com Android 13, ele precisa corrigir a partição `init_boot` em vez da partição `boot`, enquanto o modo GKI sempre opera sobre a partição `boot`.
|
||||
|
||||
### Use o gerenciador
|
||||
|
||||
Abra o gerenciador, clique no ícone de instalação no canto superior direito e diversas opções aparecerão:
|
||||
|
||||
1. Selecione um arquivo. Se o seu dispositivo não tiver privilégios root, você pode escolher esta opção e, em seguida, selecionar o seu firmware oficial. O gerenciador corrigirá automaticamente o firmware. Após isso, basta fazer o flash deste arquivo corrigido para obter privilégios root permanentemente.
|
||||
2. Instalação direta. Se o seu dispositivo já estiver rooteado, você pode escolher esta opção. O gerenciador obterá automaticamente as informações do seu dispositivo, corrigirá o firmware oficial e realizará o flash automaticamente. Você também pode usar o comando `fastboot boot` junto com o kernel GKI do KernelSU para obter root temporário e instalar o gerenciador, e então usar esta opção. Esta também é a principal forma de atualizar o KernelSU.
|
||||
3. Instalar no slot inativo. Se o seu dispositivo suportar partição A/B, você pode escolher esta opção. O gerenciador corrigirá automaticamente o firmware oficial e o instalará em outra partição. Esse método é adequado para dispositivos após o OTA, você pode instalá-lo diretamente em outra partição após o OTA e, em seguida, reiniciar o dispositivo.
|
||||
|
||||
### Use a linha de comando
|
||||
|
||||
Se não quiser usar o gerenciador, você também pode usar a linha de comando para instalar o LKM. A ferramenta `ksud` fornecida pelo KernelSU pode ajudá-lo a corrigir rapidamente o firmware oficial e depois fazer o flash.
|
||||
|
||||
Esta ferramenta oferece suporte ao macOS, Linux e Windows. Você pode baixar a versão correspondente em [GitHub Release](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
Uso: `ksud boot-patch` você pode verificar a ajuda da linha de comando para opções específicas.
|
||||
|
||||
```sh
|
||||
oriole:/ # ksud boot-patch -h
|
||||
Patch boot ou imagens init_boot para aplicar o KernelSU
|
||||
|
||||
Uso: ksud boot-patch [OPTIONS]
|
||||
|
||||
Opções:
|
||||
-b, --boot <BOOT> Caminho da imagem boot. Se não especificado, tentará encontrar a imagem boot automaticamente
|
||||
-k, --kernel <KERNEL> Caminho da imagem do kernel a ser substituída
|
||||
-m, --module <MODULE> Caminho do módulo LKM a ser substituído. Se não especificado, usará o módulo integrado
|
||||
-i, --init <INIT> init a ser substituído
|
||||
-u, --ota Usará outro slot se a imagem boot não for especificada
|
||||
-f, --flash Flash para a partição boot após o patch
|
||||
-o, --out <OUT> Caminho de saída. Se não especificado, usará o diretório atual
|
||||
--magiskboot <MAGISKBOOT> Caminho do magiskboot. Se não especificado, usará a versão integrada
|
||||
--kmi <KMI> Versão do KMI. Se especificada, usará o KMI indicado
|
||||
-h, --help Imprimir ajuda
|
||||
```
|
||||
|
||||
Algumas opções que precisam ser explicadas:
|
||||
|
||||
1. A opção `--magiskboot` pode especificar o caminho do magiskboot. Se não for especificado, o ksud irá procurá-lo nas variáveis de ambiente. Se você não souber como obter o magiskboot, você pode verificar [aqui](#patch-boot-image).
|
||||
2. A opção `--kmi` pode especificar a versão do `KMI`. Se o nome do kernel do seu dispositivo não seguir a especificação KMI, você poderá especificá-lo através desta opção.
|
||||
|
||||
O uso mais comum é:
|
||||
|
||||
```sh
|
||||
ksud boot-patch -b <boot.img> --kmi android13-5.10
|
||||
```
|
||||
|
||||
## Instalação no modo GKI
|
||||
|
||||
Existem vários métodos de instalação para o modo GKI, cada um adequado para um cenário diferente, portanto escolha conforme necessário.
|
||||
|
||||
1. Instalar com fastboot usando o boot.img fornecido pelo KernelSU.
|
||||
2. Instalar com um app kernel flash, como o [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases).
|
||||
3. Corrigir manualmente o boot.img e instalá-lo.
|
||||
4. Instalar com Recovery personalizado (por exemplo, TWRP).
|
||||
|
||||
## Instalar com o boot.img fornecido pelo KernelSU
|
||||
|
||||
Se o `boot.img` do seu dispositivo usa um formato de compactação comumente usado, você pode usar as imagens GKI fornecidas pelo KernelSU para atualizá-lo diretamente. Não requer TWRP ou autocorreção da imagem.
|
||||
|
||||
### Encontre o boot.img adequado
|
||||
|
||||
O KernelSU fornece um boot.img genérico para dispositivos GKI, e você deve fazer o flash do boot.img na partição boot do dispositivo.
|
||||
|
||||
Você pode baixar o boot.img em [GitHub Release](https://github.com/tiann/KernelSU/releases). Por favor, observe que você deve usar a versão correta do boot.img. Se você não sabe qual arquivo baixar, leia atentamente a descrição do [KMI](#kmi) e [Nível do patch de segurança](#security-patch-level) neste documento.
|
||||
|
||||
Normalmente, existem três arquivos de inicialização em formatos diferentes para o mesmo KMI e nível de patch de segurança. Eles são idênticos, exceto pelo formato de compactação do kernel. Por favor, verifique o formato de compactação do kernel de seu boot.img original. Você deve usar o formato correto, como `lz4` ou `gz`. Se você usar um formato de compactação incorreto, poderá encontrar bootloop após o flash do boot.img.
|
||||
|
||||
::: info FORMATO DE COMPACTAÇÃO DO BOOT.IMG
|
||||
1. Você pode usar o magiskboot para obter o formato de compactação do seu boot.img original. Alternativamente, você também pode perguntar a membros ou desenvolvedores da comunidade que possuam o mesmo modelo de dispositivo. Além disso, o formato de compactação do kernel geralmente não muda, portanto, se você inicializar com êxito com um determinado formato de compactação, poderá tentar esse formato mais tarde.
|
||||
2. Dispositivos Xiaomi geralmente usam `gz` ou `uncompressed`.
|
||||
3. Para dispositivos Pixel, siga as instruções abaixo:
|
||||
:::
|
||||
|
||||
### Flash o boot.img para o dispositivo
|
||||
|
||||
Use o `adb` para conectar seu dispositivo, execute `adb reboot bootloader` para entrar no modo fastboot e use este comando para flashar o KernelSU:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
Se o seu dispositivo suportar `fastboot boot`, você pode usar primeiro `fastboot boot boot.img` para tentar usar o boot.img para inicializar o sistema primeiro. Se algo inesperado acontecer, reinicie-o novamente para inicializar.
|
||||
:::
|
||||
|
||||
### Reiniciar
|
||||
|
||||
Após a conclusão do flash, você deve reiniciar o dispositivo:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
## Instalar com Kernel Flasher
|
||||
|
||||
Etapa:
|
||||
|
||||
1. Baixe o ZIP AnyKernel3. Se você não sabe qual arquivo baixar, leia atentamente a descrição do [KMI](#kmi) e [Nível do patch de segurança](#security-patch-level) neste documento.
|
||||
2. Abra o app Kernel Flasher, conceda as permissões de root necessárias e use o ZIP AnyKernel3 fornecido para fazer o flash.
|
||||
|
||||
Dessa forma, é necessário que o app Kernel Flasher tenha privilégios root. Você pode usar os seguintes métodos para conseguir isso:
|
||||
|
||||
1. Seu dispositivo está rooteado. Por exemplo, você instalou o KernelSU e deseja atualizar para a versão mais recente ou fez o root por meio de outros métodos (como Magisk).
|
||||
2. Se o seu dispositivo não estiver rooteado, mas suportar o método de inicialização temporária como `fastboot boot boot.img`, você pode usar a imagem GKI fornecida pelo KernelSU para inicializar temporariamente o seu dispositivo, obter privilégios root temporário e, em seguida, usar o Kernel Flasher para obter privilégios root permanente.
|
||||
|
||||
Aqui estão alguns apps que podem ser usados para realizar o flash do kernel:
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
Observação: Este método é mais conveniente ao atualizar o KernelSU e pode ser feito sem um computador (faça um backup primeiro).
|
||||
|
||||
## Corrigir boot.img manualmente {#patch-boot-image}
|
||||
|
||||
Para alguns dispositivos, o formato boot.img não é tão comum como `lz4`, `gz` e `uncompressed`. Um exemplo típico é o Pixel, cujo boot.img é compactado no formato `lz4_legacy`, enquanto o ramdisk pode estar em `gz` ou também comprimido em `lz4_legacy`. Atualmente, se você flashar diretamente o boot.img fornecido pelo KernelSU, o dispositivo pode não conseguir inicializar. Nesse caso, é necessário corrigir manualmente o boot.img para conseguir isso.
|
||||
|
||||
É sempre recomendado usar `magiskboot` para corrigir imagens, existem duas maneiras:
|
||||
|
||||
1. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
2. [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci)
|
||||
|
||||
A versão oficial do `magiskboot` só pode ser executada em dispositivos Android, se você quiser rodar no PC, você pode tentar a segunda opção.
|
||||
|
||||
::: tip DICA
|
||||
Android-Image-Kitchen não é recomendado por enquanto, porque ele não lida corretamente com os metadados de inicialização (como o nível do patch de segurança). Portanto, pode não funcionar em alguns dispositivos.
|
||||
:::
|
||||
|
||||
### Preparação
|
||||
|
||||
1. Obtenha o boot.img padrão do dispositivo. Você pode obtê-lo com os fabricantes do seu dispositivo. Talvez você precise do [payload-dumper-go](https://github.com/ssut/payload-dumper-go).
|
||||
2. Baixe o arquivo ZIP AnyKernel3 fornecido pelo KernelSU que corresponde à versão KMI do seu dispositivo. Você pode consultar [Instalar com Recovery personalizado](#install-with-custom-recovery).
|
||||
3. Descompacte o pacote AnyKernel3 e obtenha o arquivo `Image`, que é o arquivo do kernel do KernelSU.
|
||||
|
||||
### Usando o magiskboot em dispositivos Android {#using-magiskboot-on-Android-devices}
|
||||
|
||||
1. Baixe o Magisk mais recente em [GitHub Releases](https://github.com/topjohnwu/Magisk/releases).
|
||||
2. Renomeie o `Magisk-*(versão).apk` para `Magisk-*.zip` e descompacte-o.
|
||||
3. Envie `Magisk-*/lib/arm64-v8a/libmagiskboot.so` para o seu dispositivo por ADB: `adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot`.
|
||||
4. Envie o boot.img padrão e Image em AnyKernel3 para o seu dispositivo.
|
||||
5. Entre no ADB shell e execute o diretório `cd /data/local/tmp/`, em seguida, `chmod +x magiskboot`.
|
||||
6. Entre no ADB shell e execute o diretório `cd /data/local/tmp/`, execute `./magiskboot unpack boot.img` para descompactar `boot.img`, você obterá um arquivo `kernel`, este é o seu kernel padrão.
|
||||
7. Substitua `kernel` por `Image` executando o comando: `mv -f Image kernel`.
|
||||
8. Execute `./magiskboot repack boot.img` para reembalar o boot.img, e você obterá um arquivo `new-boot.img`, faça o flash deste arquivo para o dispositivo por fastboot.
|
||||
|
||||
### Usando o magiskboot no PC Windows/macOS/Linux {#using-magiskboot-on-PC}
|
||||
|
||||
1. Baixe o `magiskboot` adequado para o seu sistema operacional em [magiskboot_build](https://github.com/ookiineko/magiskboot_build/releases/tag/last-ci).
|
||||
2. Prepare o `boot.img` padrão e `Image` em seu PC.
|
||||
3. Execute `chmod +x magiskboot`.
|
||||
4. Entre no diretório apropriado, execute `./magiskboot unpack boot.img` para descompactar `boot.img`. Você obterá um arquivo `kernel`, este é o seu kernel padrão.
|
||||
5. Substitua `kernel` por `Image` executando o comando: `mv -f Image kernel`.
|
||||
6. Execute `./magiskboot repack boot.img` para reembalar o boot.img, e você obterá um arquivo `new-boot.img`, faça o flash deste arquivo para o dispositivo por fastboot.
|
||||
|
||||
::: info INFORMAÇÕES
|
||||
O `magiskboot` oficial pode executar o dispositivo `Linux` normalmente. Se você for um usuário Linux, você pode usar a versão oficial.
|
||||
:::
|
||||
|
||||
## Instalar com Recovery personalizado {#install-with-custom-recovery}
|
||||
|
||||
Pré-requisito: Seu dispositivo deve ter um Recovery personalizado, como TWRP. Se não houver Recovery personalizado disponível para o seu dispositivo, use outro método.
|
||||
|
||||
Etapas:
|
||||
|
||||
1. Em [GitHub Releases](https://github.com/tiann/KernelSU/releases), baixe o pacote ZIP começando com AnyKernel3 que corresponde à versão do seu dispositivo. Por exemplo, a versão do kernel do dispositivo é `android12-5.10.66`, então você deve baixar o arquivo `AnyKernel3-android12-5.10.66_yyyy-MM.zip` (onde `yyyy` é o ano e `MM` é o mês).
|
||||
2. Reinicie o dispositivo no TWRP.
|
||||
3. Use o ADB para colocar AnyKernel3-*.zip no dispositivo em `/sdcard` e escolha instalá-lo na interface do TWRP, ou você pode diretamente executar `adb sideload AnyKernel-*.zip` para instalar.
|
||||
|
||||
Observação: Este método é adequado para qualquer instalação (não limitado à instalação inicial ou atualizações subsequentes), desde que você use o TWRP.
|
||||
|
||||
## Outros métodos
|
||||
|
||||
Na verdade, todos esses métodos de instalação têm apenas uma ideia principal, que é **substituir o kernel original pelo fornecido pelo KernelSU**, desde que isso possa ser alcançado, ele pode ser instalado. A seguir estão outros métodos possíveis:
|
||||
|
||||
1. Primeiro instale o Magisk, obtenha privilégios root através do Magisk e então use o Kernel Flasher para fazer o flash no ZIP AnyKernel3 do KernelSU.
|
||||
2. Use algum kit de ferramentas de flash em PC para flashar no kernel fornecido pelo KernelSU.
|
||||
|
||||
No entanto, se não funcionar, por favor, tente o método `magiskboot`.
|
||||
@@ -1,48 +0,0 @@
|
||||
# Módulo WebUI
|
||||
|
||||
Além de executar scripts de inicialização e modificar arquivos do sistema, os módulos do KernelSU também suportam a exibição de interfaces da UI e à interação direta com os usuários.
|
||||
|
||||
O módulo pode escrever páginas HTML + CSS + JavaScript através de qualquer tecnologia web. O gerenciador do KernelSU exibirá essas páginas através do WebView. Ele também fornece algumas APIs para interagir com o sistema, como executar comandos shell.
|
||||
|
||||
## Diretório `webroot`
|
||||
|
||||
Os arquivos de recursos da web devem ser colocados no subdiretório `webroot` do diretório raiz do módulo, e **DEVE** haver um arquivo chamado `index.html`, que é a entrada da página do módulo. A estrutura do módulo mais simples contendo uma interface web é a seguinte:
|
||||
|
||||
```txt
|
||||
❯ tree .
|
||||
.
|
||||
|-- module.prop
|
||||
`-- webroot
|
||||
`-- index.html
|
||||
```
|
||||
|
||||
::: warning AVISO
|
||||
Ao instalar o módulo, KernelSU definirá automaticamente as permissões e o contexto do SELinux deste diretório. Se você não sabe o que está fazendo, não defina você mesmo as permissões deste diretório!
|
||||
:::
|
||||
|
||||
Se sua página contém CSS e JavaScript, você também precisa colocá-la neste diretório.
|
||||
|
||||
## API JavaScript
|
||||
|
||||
Se for apenas uma página de exibição, ela funcionará como uma página web comum. No entanto, o mais importante é que o KernelSU oferece uma série de APIs de sistema, permitindo a implementação de funções exclusivas do módulo.
|
||||
|
||||
O KernelSU disponibiliza uma biblioteca JavaScript, que está publicada no [npm](https://www.npmjs.com/package/kernelsu) e pode ser usada no código JavaScript das suas páginas web.
|
||||
|
||||
Por exemplo, você pode executar um comando shell para obter uma configuração específica ou modificar uma propriedade:
|
||||
|
||||
```JavaScript
|
||||
import { exec } from 'kernelsu';
|
||||
|
||||
const { errno, stdout } = exec("getprop ro.product.model");
|
||||
```
|
||||
|
||||
Para outro exemplo, você pode fazer com que a página web seja exibida em tela inteira ou exibir um dica.
|
||||
|
||||
[Documentação da API](https://www.npmjs.com/package/kernelsu)
|
||||
|
||||
Se você achar que a API existente não atende às suas necessidades ou é inconveniente de usar, fique à vontade para nos dar sugestões [aqui](https://github.com/tiann/KernelSU/issues)!
|
||||
|
||||
## Algumas dicas
|
||||
|
||||
1. Você pode usar `localStorage` normalmente para armazenar alguns dados, mas tenha em mente que eles serão perdidos caso o app gerenciador seja desinstalado. Se precisar de armazenamento persistente, será necessário gravar os dados manualmente em algum diretório.
|
||||
2. Para páginas simples, recomendamos o uso do [parceljs](https://parceljs.org/) para empacotamento. Ele não exige configuração inicial e é extremamente prático de usar. No entanto, se você é um especialista em front-end ou possui suas próprias preferências, sinta-se à vontade para usar a ferramenta de sua escolha!
|
||||
@@ -1,326 +0,0 @@
|
||||
# Guias de módulo
|
||||
|
||||
O KernelSU fornece um mecanismo de módulo que consegue modificar o diretório do sistema enquanto mantém a integridade da partição do sistema. Esse mecanismo é conhecido como "sem sistema".
|
||||
|
||||
O mecanismo de módulos do KernelSU é quase o mesmo do Magisk. Se você já está familiarizado com o desenvolvimento de módulos Magisk, o desenvolvimento de módulos KernelSU é muito semelhante. Você pode pular a introdução dos módulos abaixo e só precisa ler [Diferenças com Magisk](difference-with-magisk.md).
|
||||
|
||||
## WebUI
|
||||
|
||||
Os módulos do KernelSU suportam a exibição de interfaces e a interação com os usuários. Para mais detalhes, consulte a [documentação do WebUI](module-webui.md).
|
||||
|
||||
## BusyBox
|
||||
|
||||
O KernelSU vem com um recurso binário BusyBox completo (incluindo suporte completo ao SELinux). O executável está localizado em `/data/adb/ksu/bin/busybox`. O BusyBox do KernelSU suporta "ASH Standalone Shell Mode" alternável em tempo de execução. O que este Modo Autônomo significa é que ao executar no shell `ash` do BusyBox, cada comando usará diretamente o miniaplicativo dentro do BusyBox, independentemente do que estiver definido em `PATH`. Por exemplo, comandos como `ls`, `rm`, `chmod` **NÃO** usarão o que está em `PATH` (no caso do Android, por padrão será `/system/bin/ls`, `/system/bin/rm` e `/system/bin/chmod` respectivamente), mas em vez disso chamará diretamente os miniaplicativos internos do BusyBox. Isso garante que os scripts sempre sejam executados em um ambiente previsível e sempre tenham o conjunto completo de comandos, independentemente da versão do Android em que estão sendo executados. Para forçar um comando a **NÃO** usar o BusyBox, você deve chamar o executável com caminhos completos.
|
||||
|
||||
Cada script shell executado no contexto do KernelSU será executado no shell `ash` do BusyBox com o Modo Autônomo ativado. Para o que é relevante para desenvolvedores terceirizados, isso inclui todos os scripts de inicialização e scripts de instalação de módulos.
|
||||
|
||||
Para aqueles que desejam usar o recurso Modo Autônomo fora do KernelSU, existem 2 maneiras de ativá-los:
|
||||
|
||||
1. Definir a variável de ambiente `ASH_STANDALONE` como `1`.<br>Exemplo: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Alternar com opções de linha de comando:<br>`/data/adb/ksu/bin/busybox sh -o standalone <script>`
|
||||
|
||||
Para garantir que todos os shells `sh` subsequentes executados também sejam executados no Modo Autônomo, a opção 1 é o método preferido (e é isso que o KernelSU e o gerenciador do KernelSU usam internamente), pois as variáveis de ambiente são herdadas para os subprocesso.
|
||||
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
O BusyBox do KernelSU agora está usando o arquivo binário compilado diretamente do projeto Magisk. **Obrigado ao Magisk!** Portanto, você não precisa se preocupar com problemas de compatibilidade entre scripts BusyBox no Magisk e KernelSU porque eles são exatamente iguais!
|
||||
:::
|
||||
|
||||
## Módulos KernelSU
|
||||
|
||||
Um módulo KernelSU é uma pasta colocada em `/data/adb/modules` com a estrutura abaixo:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- A pasta é nomeada com o ID do módulo
|
||||
│ │
|
||||
│ │ *** Identidade do módulo ***
|
||||
│ │
|
||||
│ ├── module.prop <--- Este arquivo armazena os metadados do módulo
|
||||
│ │
|
||||
│ │ *** Conteúdo principal ***
|
||||
│ │
|
||||
│ ├── system <--- Esta pasta será montada se skip_mount não existir
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** Sinalizadores de status ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- Se existir, o KernelSU não montará sua pasta de sistema
|
||||
│ ├── disable <--- Se existir, o módulo será desativado
|
||||
│ ├── remove <--- Se existir, o módulo será removido na próxima reinicialização
|
||||
│ │
|
||||
│ │ *** Arquivos opcionais ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- Este script será executado em post-fs-data
|
||||
│ ├── post-mount.sh <--- Este script será executado em post-mount
|
||||
│ ├── service.sh <--- Este script será executado no serviço late_start
|
||||
│ ├── boot-completed.sh <--- Este script será executado na inicialização concluída
|
||||
| ├── uninstall.sh <--- Este script será executado quando o KernelSU remover seu módulo
|
||||
| ├── action.sh <--- Este script será executado quando o usuário clicar no botão Ação no KernelSU
|
||||
│ ├── system.prop <--- As propriedades neste arquivo serão carregadas como propriedades do sistema por resetprop
|
||||
│ ├── sepolicy.rule <--- Regras adicionais do sepolicy personalizadas
|
||||
│ │
|
||||
│ │ *** Gerado automaticamente, NÃO CRIE OU MODIFIQUE MANUALMENTE ***
|
||||
│ │
|
||||
│ ├── vendor <--- Um link simbólico para $MODID/system/vendor
|
||||
│ ├── product <--- Um link simbólico para $MODID/system/product
|
||||
│ ├── system_ext <--- Um link simbólico para $MODID/system/system_ext
|
||||
│ │
|
||||
│ │ *** Quaisquer arquivos/pastas adicionais são permitidos ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
O KernelSU não possui suporte integrado para o Zygisk, portanto não há conteúdo relacionado ao Zygisk no módulo. No entanto, você pode usar [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) para suportar módulos Zygisk. Neste caso, o conteúdo do módulo Zygisk é idêntico ao suportado pelo Magisk.
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
`module.prop` é um arquivo de configuração para um módulo. No KernelSU, se um módulo não contiver este arquivo, ele não será reconhecido como um módulo. O formato deste arquivo é o seguinte:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versionCode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` deve corresponder a esta expressão regular: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
Exemplo: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
Este é o **identificador exclusivo** do seu módulo. Você não deve alterá-lo depois de publicado.
|
||||
- `versionCode` deve ser um **número inteiro**. Isso é usado para comparar versões.
|
||||
- Outros que não foram mencionados acima podem ser qualquer string de **linha única**.
|
||||
- Certifique-se de usar o tipo de quebra de linha `UNIX (LF)` e não o `Windows (CR+LF)` ou `Macintosh (CR)`.
|
||||
|
||||
### Shell scripts
|
||||
|
||||
Por favor, leia a seção [Scripts de inicialização](#scripts-de-inicializacao) para entender a diferença entre `post-fs-data.sh` e `service.sh`. Para a maioria dos desenvolvedores de módulos, `service.sh` deve ser bom o suficiente se você precisar apenas executar um script de inicialização. Se precisar executar o script após a inicialização ser concluída, use `boot-completed.sh`. Se você quiser fazer algo após montar OverlayFS, use `post-mount.sh`.
|
||||
|
||||
Em todos os scripts do seu módulo, use `MODDIR=${0%/*}` para obter o caminho do diretório base do seu módulo, **NÃO** codifique o caminho do seu módulo nos scripts.
|
||||
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
Você pode usar a variável de ambiente `KSU` para determinar se um script está sendo executado no KernelSU ou Magisk. Se estiver executando no KernelSU, esse valor será definido como `true`.
|
||||
:::
|
||||
|
||||
### Diretório `system`
|
||||
|
||||
O conteúdo deste diretório será sobreposto à partição `/system` do sistema usando OverlayFS após a inicialização do sistema. Isso significa que:
|
||||
|
||||
1. Arquivos com o mesmo nome daqueles no diretório correspondente no sistema serão substituídos pelos arquivos deste diretório.
|
||||
2. Pastas com o mesmo nome daquelas no diretório correspondente no sistema serão mescladas com as pastas neste diretório.
|
||||
|
||||
Se você deseja excluir um arquivo ou pasta no diretório original do sistema, você precisa criar um arquivo com o mesmo nome do arquivo/pasta no diretório do módulo usando `mknod filename c 0 0`. Dessa forma, o sistema OverlayFS irá automaticamente "branquear" este arquivo como se ele tivesse sido excluído (a partição /system não foi realmente alterada).
|
||||
|
||||
Você também pode declarar uma variável chamada `REMOVE` contendo uma lista de diretórios em `customize.sh` para executar operações de remoção, e o KernelSU executará automaticamente `mknod <TARGET> c 0 0` nos diretórios correspondentes do módulo. Por exemplo:
|
||||
|
||||
```sh
|
||||
REMOVE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
A lista acima irá executar `mknod $MODPATH/system/app/YouTube c 0 0` e `mknod $MODPATH/system/app/Bloatware c 0 0`, `/system/app/YouTube` e `/system/app/Bloatware` serão removidos após o módulo entrar em vigor.
|
||||
|
||||
Se você deseja substituir um diretório no sistema, você precisa criar um diretório com o mesmo caminho no diretório do módulo e, em seguida, definir o atributo `setfattr -n trusted.overlay.opaque -v y <TARGET>` para este diretório. Desta forma, o sistema OverlayFS substituirá automaticamente o diretório correspondente no sistema (sem alterar a partição /system).
|
||||
|
||||
Você pode declarar uma variável chamada `REPLACE` em seu arquivo `customize.sh`, que inclui uma lista de diretórios a serem substituídos, e o KernelSU executará automaticamente as operações correspondentes em seu diretório de módulo. Por exemplo:
|
||||
|
||||
```sh
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
Esta lista criará automaticamente os diretórios `$MODPATH/system/app/YouTube` e `$MODPATH/system/app/Bloatware` e, em seguida, executará `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` e `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. Após o módulo entrar em vigor, `/system/app/YouTube` e `/system/app/Bloatware` serão substituídos por diretórios vazios.
|
||||
|
||||
::: tip DIFERENÇAS COM MAGISK
|
||||
O mecanismo sem sistema do KernelSU é implementado através do OverlayFS do kernel, enquanto o Magisk atualmente usa montagem mágica (montagem de ligação). Os dois métodos de implementação têm diferenças significativas, mas o objetivo final é o mesmo: modificar os arquivos /system sem modificar fisicamente a partição /system.
|
||||
:::
|
||||
|
||||
Se você estiver interessado em OverlayFS, é recomendável ler a [documentação sobre OverlayFS](https://docs.kernel.org/filesystems/overlayfs.html) do kernel Linux.
|
||||
|
||||
### system.prop
|
||||
|
||||
Este arquivo segue o mesmo formato de `build.prop`. Cada linha é composta por `[key]=[value]`.
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
Se o seu módulo exigir alguns patches adicionais do sepolicy, adicione essas regras a este arquivo. Cada linha neste arquivo será tratada como uma declaração de política.
|
||||
|
||||
## Instalador do módulo
|
||||
|
||||
Um instalador do módulo KernelSU é um módulo KernelSU empacotado em um arquivo ZIP que pode ser atualizado no gerenciador do KernelSU. O instalador do módulo KernelSU mais simples é apenas um módulo KernelSU compactado como um arquivo ZIP.
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (Opcional, mais detalhes posteriormente)
|
||||
│ Este script será fornecido por update-binary
|
||||
├── ...
|
||||
├── ... /* O resto dos arquivos do módulo */
|
||||
│
|
||||
```
|
||||
|
||||
::: warning AVISO
|
||||
O módulo KernelSU **NÃO** é compatível para instalação no Recovery personalizado!
|
||||
:::
|
||||
|
||||
### Personalização
|
||||
|
||||
Se você precisar personalizar o processo de instalação do módulo, opcionalmente você pode criar um script no instalador chamado `customize.sh`. Este script será **sourced** (não executado) pelo script do instalador do módulo depois que todos os arquivos forem extraídos e as permissões padrão e o contexto secundário forem aplicados. Isso é muito útil se o seu módulo exigir configuração adicional com base na ABI do dispositivo ou se você precisar definir permissões/secontext especiais para alguns dos arquivos do seu módulo.
|
||||
|
||||
Se você quiser controlar e personalizar totalmente o processo de instalação, declare `SKIPUNZIP=1` em `customize.sh` para pular todas as etapas de instalação padrão. Ao fazer isso, seu `customize.sh` será responsável por instalar tudo sozinho.
|
||||
|
||||
O script `customize.sh` é executado no shell BusyBox `ash` do KernelSU com o Modo Autônomo ativado. As seguintes variáveis e funções estão disponíveis:
|
||||
|
||||
#### Variáveis
|
||||
|
||||
- `KSU` (bool): uma variável para marcar que o script está sendo executado no ambiente KernelSU, e o valor desta variável sempre será `true`. Você pode usá-lo para distinguir entre KernelSU e Magisk.
|
||||
- `KSU_VER` (string): a string da versão do KernelSU atualmente instalado (ex.: `v0.4.0`).
|
||||
- `KSU_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do usuário (ex.: `10672`).
|
||||
- `KSU_KERNEL_VER_CODE` (int): o código da versão do KernelSU atualmente instalado no espaço do kernel (ex.: `10672`).
|
||||
- `BOOTMODE` (bool): sempre será `true` no KernelSU.
|
||||
- `MODPATH` (path): o caminho onde os arquivos do seu módulo devem ser instalados.
|
||||
- `TMPDIR` (path): um lugar onde você pode armazenar arquivos temporariamente.
|
||||
- `ZIPFILE` (path): ZIP de instalação do seu módulo.
|
||||
- `ARCH` (string): a arquitetura da CPU do dispositivo. O valor é `arm`, `arm64`, `x86` ou `x64`.
|
||||
- `IS64BIT` (bool): `true` se `$ARCH` for `arm64` ou `x64`.
|
||||
- `API` (int): o nível da API (versão do Android) do dispositivo (ex.: `23` para Android 6.0).
|
||||
|
||||
::: warning AVISO
|
||||
No KernelSU, `MAGISK_VER_CODE` é sempre `25200` e `MAGISK_VER` é sempre `v25.2`. Por favor, não use essas duas variáveis para determinar se ele está sendo executado no KernelSU ou não.
|
||||
:::
|
||||
|
||||
#### Funções
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
imprima <msg> no console
|
||||
Evite usar 'echo', pois ele não será exibido no console de recovery personalizado
|
||||
|
||||
abort <msg>
|
||||
imprima mensagem de erro <msg> para consolar e encerrar a instalação
|
||||
Evite usar 'exit', pois isso irá pular as etapas de limpeza de encerramento
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
se [context] não estiver definido, o padrão é "u:object_r:system_file:s0"
|
||||
esta função é uma abreviação para os seguintes comandos:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
se [context] não está definido, o padrão é "u:object_r:system_file:s0"
|
||||
para todos os arquivos em <directory>, ele chamará:
|
||||
set_perm arquivo proprietário do grupo filepermission
|
||||
para todos os diretórios em <directory> (including itself), ele vai ligar:
|
||||
set_perm dir owner group dirpermission context
|
||||
```
|
||||
|
||||
## Scripts de inicialização
|
||||
|
||||
No KernelSU, os scripts são divididos em dois tipos com base em seu modo de execução: modo post-fs-data e modo de serviço late_start.
|
||||
|
||||
- modo post-fs-data
|
||||
- Esta etapa está BLOQUEANDO. O processo de inicialização é pausado antes da conclusão da execução ou após 10 segundos.
|
||||
- Os scripts são executados antes de qualquer módulo ser montado. Isso permite que um desenvolvedor de módulo ajuste dinamicamente seus módulos antes de serem montados.
|
||||
- Este estágio acontece antes do início do Zygote, o que significa praticamente tudo no Android.
|
||||
- **AVISO:** Usar `setprop` irá bloquear o processo de inicialização! Por favor, use `resetprop -n <prop_name> <prop_value>` em vez disso.
|
||||
- **Execute scripts neste modo apenas se necessário**.
|
||||
- modo de serviço late_start
|
||||
- Esta etapa é SEM BLOQUEIO. Seu script é executado em paralelo com o restante do processo de inicialização.
|
||||
- **Este é o estágio recomendado para executar a maioria dos scripts**.
|
||||
|
||||
No KernelSU, os scripts de inicialização são divididos em dois tipos com base no local de armazenamento: scripts gerais e scripts de módulo.
|
||||
|
||||
- Scripts gerais
|
||||
- Colocado em `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` ou `/data/adb/boot-completed.d`.
|
||||
- Somente executado se o script estiver definido como executável (`chmod +x script.sh`).
|
||||
- Os scripts em `post-fs-data.d` são executados no modo post-fs-data e os scripts em `service.d` são executados no modo de serviço late_start.
|
||||
- Os módulos **NÃO** devem adicionar scripts gerais durante a instalação.
|
||||
- Scripts de módulo
|
||||
- Colocado na própria pasta do módulo.
|
||||
- Executado apenas se o módulo estiver ativado.
|
||||
- `post-fs-data.sh` é executado no modo post-fs-data, `service.sh` é executado no modo de serviço late_start, `boot-completed.sh` é executado na inicialização concluída e `post-mount.sh` é executado no OverlayFS montado.
|
||||
|
||||
Todos os scripts de inicialização serão executados no shell BusyBox `ash` do KernelSU com o Modo Autônomo ativado.
|
||||
|
||||
### Explicação do processo de scripts de inicialização
|
||||
|
||||
A seguir está o processo de inicialização relevante para o Android (algumas partes foram omitidas), que inclui a operação do KernelSU (com asteriscos iniciais) e pode ajudá-lo a entender melhor o propósito desses scripts de módulo:
|
||||
|
||||
```txt
|
||||
0. Bootloader (nada nesta tela)
|
||||
load patched boot.img
|
||||
load kernel:
|
||||
- Modo GKI: kernel GKI com KernelSU integrado
|
||||
- Modo LKM: kernel stock
|
||||
...
|
||||
|
||||
1. kernel exec init (logo OEM na tela):
|
||||
- Modo GKI: stock init
|
||||
- Modo LKM: exec ksuinit, insmod kernelsu.ko, exec stock init
|
||||
mount /dev, /dev/pts, /proc, /sys, etc.
|
||||
property-init -> read default props
|
||||
read init.rc
|
||||
...
|
||||
early-init -> init -> late_init
|
||||
early-fs
|
||||
start vold
|
||||
fs
|
||||
mount /vendor, /system, /persist, etc.
|
||||
post-fs-data
|
||||
*verificação do modo de segurança
|
||||
*executar scripts gerais em post-fs-data.d/
|
||||
*carregar sepolicy.rule
|
||||
*montar tmpfs
|
||||
*executar scripts de módulo post-fs-data.sh
|
||||
**(Zygisk)./bin/zygisk-ptrace64 monitor
|
||||
*(pré)carregamento de system.prop (igual a resetprop -n)
|
||||
*remontar módulos em /system
|
||||
*executar scripts gerais em post-mount.d/
|
||||
*executar scripts de módulo post-mount.sh
|
||||
zygote-start
|
||||
load_all_props_action
|
||||
*executar resetprop (defina adereços reais para resetprop com a opção -n)
|
||||
... -> boot
|
||||
class_start core
|
||||
start-service logd, console, vold, etc.
|
||||
class_start main
|
||||
start-service adb, netd (iptables), zygote, etc.
|
||||
|
||||
2. kernel2user init (animação da ROM na tela, inicie pelo serviço bootanim)
|
||||
*executar scripts gerais em service.d/
|
||||
*executar scripts de módulo service.sh
|
||||
*definir adereços para resetprop sem a opção -p
|
||||
**(Zygisk) hook zygote (iniciar o zygiskd)
|
||||
**(Zygisk) montar zygisksu/module.prop
|
||||
iniciar apps do sistema (início automático)
|
||||
...
|
||||
inicialização completa (transmitir evento ACTION_BOOT_COMPLETED)
|
||||
*executar scripts gerais em boot-completed.d/
|
||||
*executar scripts de módulo boot-completed.sh
|
||||
|
||||
3. Operável pelo usuário (tela de bloqueio)
|
||||
insira a senha para descriptografar /data/data
|
||||
*conjunto real de adereços para resetprop com opção -p
|
||||
iniciar apps de usuário (início automático)
|
||||
```
|
||||
|
||||
Se você estiver interessado na linguagem de inicialização do Android, é recomendável ler sua [documentação](https://android.googlesource.com/platform/system/core/+/master/init/README.md).
|
||||
@@ -1,50 +0,0 @@
|
||||
# Resgate do bootloop
|
||||
|
||||
Ao atualizar um dispositivo, podem ocorrer situações em que o dispositivo fica "bloqueado". Em teoria, se você usar o fastboot apenas para atualizar a partição boot ou instalar módulos inadequados que causam falha na inicialização do dispositivo, isso pode ser restaurado por meio de operações apropriadas. Este documento tem como objetivo fornecer alguns métodos de emergência para ajudá-lo a recuperar um dispositivo "bloqueado".
|
||||
|
||||
## Bloqueio por flashar partição boot
|
||||
|
||||
No KernelSU, as seguintes situações podem causar bloqueio de inicialização ao flashar a partição boot:
|
||||
|
||||
1. Você flashou uma imagem boot no formato errado. Por exemplo, se o formato de boot do seu dispositivo for `gz`, mas você flashou uma imagem no formato `lz4`, o dispositivo não inicializá.
|
||||
2. Seu dispositivo precisa desativar a verificação AVB para inicializar corretamente, o que geralmente exige a limpeza de todos os dados do dispositivo.
|
||||
3. Seu kernel tem alguns bugs ou não é adequado para o flash do seu dispositivo.
|
||||
|
||||
Não importa qual seja a situação, você pode recuperar **flashando a imagem de boot padrão**. Portanto, no início do guia de instalação, recomendamos fortemente que você faça backup de seu boot padrão antes de realizar o flash. Se você não fez backup, poderá obter o boot original de fábrica de outros usuários com o mesmo dispositivo ou do firmware oficial.
|
||||
|
||||
## Bloqueio por módulos
|
||||
|
||||
A instalação de módulos pode ser uma das causas mais comuns de bloqueio do seu dispositivo, mas devemos alertá-lo seriamente: **NÃO INSTALE MÓDULOS DE FONTES DESCONHECIDAS!** Como os módulos têm privilégios root, eles podem causar danos irreversíveis ao seu dispositivo!
|
||||
|
||||
### Módulos normais
|
||||
|
||||
Se você instalou um módulo que foi comprovadamente seguro, mas faz com que seu dispositivo não inicialize, então esta situação é facilmente recuperável no KernelSU sem qualquer preocupação. O KernelSU possui mecanismos integrados para recuperar seu dispositivo, incluindo o seguinte:
|
||||
|
||||
1. Atualização AB
|
||||
2. Recupere pressionando o botão de diminuir volume
|
||||
|
||||
#### Atualização AB
|
||||
|
||||
As atualizações do módulo KernelSU são baseadas no mecanismo de atualização AB do sistema Android usado em atualizações OTA. Quando você instala um novo módulo ou atualiza um existente, isso não modifica diretamente o arquivo do módulo atualmente em uso. Em vez disso, todos os módulos são integrados em uma nova imagem de atualização. Após o sistema ser reiniciado, ele tentará iniciar usando essa nova imagem de atualização. Se o sistema Android inicializar com sucesso, os módulos serão efetivamente atualizados.
|
||||
|
||||
Portanto, o método mais simples e comumente usado para recuperar seu dispositivo é **forçar uma reinicialização**. Se você não conseguir iniciar o sistema após instalar um módulo, pode pressionar e segurar o botão liga/desliga por mais de 10 segundos, e o sistema será reiniciado automaticamente. Após a reinicialização, ele retornará ao estado anterior à atualização do módulo, e os módulos atualizados serão desativados automaticamente.
|
||||
|
||||
#### Recupere pressionando o botão de diminuir volume
|
||||
|
||||
Se a Atualização AB ainda não resolveu o problema, você pode tentar usar o **Modo de Segurança**. Nesse modo, todos os módulos são desativados.
|
||||
|
||||
Existem duas maneiras de entrar no Modo de Segurança:
|
||||
|
||||
1. O Modo de Segurança integrado de alguns sistemas: Alguns sistemas possuem um Modo de Segurança integrado que pode ser acessado pressionando longamente o botão de diminuir volume. Em outros sistemas (como o HyperOS), o Modo de Segurança pode ser ativado a partir do Recovery. Ao entrar no Modo de Segurança do sistema, o KernelSU também entrará nesse modo e desativará automaticamente os módulos.
|
||||
2. O Modo de Segurança integrado do KernelSU: Nesse caso, o método é **pressionar a tecla de diminuir volume continuamente por mais de três vezes** após a primeira tela de inicialização.
|
||||
|
||||
Após entrar no Modo de Segurança, todos os módulos na página Módulos do gerenciador do KernelSU serão desativados. Porém, você ainda pode realizar a operação de "desinstalação" para desinstalar quaisquer módulos que possam estar causando problemas.
|
||||
|
||||
O Modo de Segurança integrado é implementado no kernel, portanto não há possibilidade de perder eventos importantes devido à interceptação. No entanto, para kernels não-GKI, pode ser necessária uma integração manual do código. Para isso, consulte a documentação oficial para orientações.
|
||||
|
||||
### Módulos maliciosos
|
||||
|
||||
Se os métodos acima não conseguirem recuperar seu dispositivo, é muito provável que o módulo que você instalou tenha operações maliciosas ou tenha danificado seu dispositivo de outra forma. Nesse caso, há apenas duas sugestões:
|
||||
|
||||
1. Limpar os dados e instalar o sistema oficial.
|
||||
2. Consultar o serviço pós-venda.
|
||||
@@ -1,30 +0,0 @@
|
||||
# Dispositivos com suporte não oficial
|
||||
|
||||
::: warning AVISO
|
||||
Nesta página, existem kernels para dispositivos não-GKI que suportam o KernelSU mantidos por outros desenvolvedores.
|
||||
:::
|
||||
|
||||
::: warning AVISO
|
||||
Esta página é destinada apenas para ajudá-lo a encontrar o código-fonte correspondente ao seu dispositivo. **NÃO** significa que o código-fonte foi revisado pelos desenvolvedores do KernelSU. Você deve usá-lo por sua própria conta e risco.
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mantenedor</th>
|
||||
<th>Repositório</th>
|
||||
<th>Dispositivos suportados</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# O que é KernelSU?
|
||||
|
||||
O KernelSU é uma solução root para dispositivos Android GKI, funciona no modo kernel e concede privilégios root para apps do espaço do usuário diretamente no espaço do kernel.
|
||||
|
||||
## Características
|
||||
|
||||
A principal característica do KernelSU é que ele é baseado em kernel. O KernelSU funciona no modo kernel, portanto pode fornecer uma interface de kernel que nunca tivemos antes. Por exemplo, é possível adicionar pontos de interrupção de hardware a qualquer processo no modo kernel, acessar a memória física de qualquer processo de forma invisível, interceptar qualquer chamada de sistema (syscall) no espaço do kernel, entre outras funcionalidades.
|
||||
|
||||
E também, o KernelSU fornece um sistema de módulos via OverlayFS, que permite carregar seu plugin personalizado no sistema. Ele também fornece um mecanismo para modificar arquivos na partição `/system`.
|
||||
|
||||
## Como usar o KernelSU?
|
||||
|
||||
Por favor, consulte: [Instalação](installation)
|
||||
|
||||
## Como compilar o KernelSU?
|
||||
|
||||
Por favor, consulte: [Como compilar](how-to-build)
|
||||
|
||||
## Discussão
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Início
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: Uma solução root baseada em kernel para Android
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Iniciar
|
||||
link: /pt_BR/guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: Ver no GitHub
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: Baseado em kernel
|
||||
details: Como o nome sugere, KernelSU funciona no kernel Linux, dando-lhe mais controle sobre os apps do espaço do usuário.
|
||||
- title: Controle de acesso root
|
||||
details: Somente apps permitidos podem acessar ou ver su, todos os outros apps não estão cientes disso.
|
||||
- title: Privilégios root personalizáveis
|
||||
details: KernelSU permite a personalização de su, uid, gid, grupos, capacidades e regras do SELinux, bloqueando privilégios root.
|
||||
- title: Módulos
|
||||
details: Os módulos podem modificar /system sem sistema usando OverlayFS proporcionando flexibilidade significativa.
|
||||
@@ -1 +0,0 @@
|
||||
google.com, pub-2610070972052494, DIRECT, f08c47fec0942fa0
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 342 B |
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"id":"adaway.root",
|
||||
"name":"Adaway Root",
|
||||
"author":"JohnRTitor",
|
||||
"description":"Only essential permissions to let Adaway modify hosts file and operate a web server.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"ROOT"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_SYS_PTRACE"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"namespace":"INHERITED",
|
||||
"locales": {
|
||||
"zh_TW": {
|
||||
"name": "Adaway Root",
|
||||
"description": "僅允許 Adaway 修改 hosts 和執行 Web 伺服器的必要權限"
|
||||
},
|
||||
"bn": {
|
||||
"name": "অ্যাডঅ্যাওয়ে রুট",
|
||||
"description": "অ্যাডঅ্যাওয়ে সিস্টেমের হোস্ট ফাইল পরিবর্তন এবং ওয়েবসার্ভার চালু করতে কমপক্ষে যা অনুমতি লাগে।"
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Adaway Root",
|
||||
"description": "Apenas permissões essenciais para permitir que Adaway modifique o arquivo hosts e opere um servidor web."
|
||||
},
|
||||
"tr": {
|
||||
"name": "Adaway Root",
|
||||
"description": "Adaway'in hosts dosyasını değiştirmesine ve bir web sunucusunu çalıştırmasına izin vermek için gerekli izinler."
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Adaway Root",
|
||||
"description": "Concede le autorizzazioni essenziali affinché Adaway possa modificare il file host e gestire un server web. "
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"id":"adb",
|
||||
"name":"Adb",
|
||||
"author":"kernelsu.org",
|
||||
"description":"Minimal rules required by most apps using ADB privilege.",
|
||||
"uid":2000,
|
||||
"gid":2000,
|
||||
"groups":[
|
||||
"ADB"
|
||||
],
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "এডিবি",
|
||||
"description": "নূন্যতম অনুমতি যার দ্বারা এডিবি স্বচ্ছন্দে কাজ করতে পারে।"
|
||||
},
|
||||
"zh_CN": {
|
||||
"name": "Adb 模版",
|
||||
"description": "大多数使用 ADB 权限应用所需要的最小权限"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Adb",
|
||||
"description": "大多數使用 ADB 權限應用程式所需要的最低權限"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Adb",
|
||||
"description": "ADB ayrıcalığını kullanan çoğu uygulama için gereken minimum kurallar."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Adb",
|
||||
"description": "Regras mínimas exigidas pela maioria dos apps que usam privilégio ADB."
|
||||
},
|
||||
"ja": {
|
||||
"name": "Adb",
|
||||
"description": "ほとんどのアプリが使用するために必要な最小限のルール ADB."
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Adb",
|
||||
"description": "Autorizzazioni minime richieste dalla maggior parte delle app che usano i privilegi di ADB."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"id":"cemiuiler.readproc",
|
||||
"name":"Cemiuiler",
|
||||
"author":"refined-fish",
|
||||
"description":"Grant Cemiuiler the minimum permissions to work properly-to restart the application.",
|
||||
"namespace":"INHERITED",
|
||||
"uid":10000,
|
||||
"gid":10000,
|
||||
"groups":[
|
||||
"READPROC"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_KILL"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"rules":"",
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "সিমিউলার",
|
||||
"description": "নূন্যতম অনুমতি যার দ্বারা সিমিউলার আবার কাজে বহাল হতে পারে।"
|
||||
},
|
||||
"zh_CN": {
|
||||
"name": "西米露Cemiuiler",
|
||||
"description": "授予Cemiuiler能正常工作——重启作用域应用的最小限度权限。"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Cemiuiler",
|
||||
"description": "授予Cemiuiler能正常運作-重啟作用域應用程式的最低權限"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Cemiuiler",
|
||||
"description": "Cemiuiler uygulamasına düzgün çalışması için minimum izinleri verin."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Cemiuiler",
|
||||
"description": "Conceda ao Cemiuiler as permissões mínimas para funcionar corretamente para reiniciar o app."
|
||||
},
|
||||
"ja": {
|
||||
"name": "Cemiuiler",
|
||||
"description": "Cemiuiler に適切に動作するための最小限の権限を付与し、アプリケーションを再起動します。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Cemiuiler",
|
||||
"description": "Concedi a Cemiuiler le autorizzazioni minime per riavviare correttamente l'applicazione."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"id":"incompetent.root",
|
||||
"name":"Incompetent root",
|
||||
"author":"kernelsu.org",
|
||||
"description":"A incompetent root user without any capability.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"ROOT"
|
||||
],
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "অযোগ্য রুট ইউজার",
|
||||
"description": "অযোগ্য রুট ইউজার যার কোনো স্পেশাল ক্ষমতা নেই।"
|
||||
},
|
||||
"zh_CN": {
|
||||
"name": "无能的 Root",
|
||||
"description": "无任何权能的 root 用户。"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "無能的 Root",
|
||||
"description": "無任何權限的 root"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Yetersiz root",
|
||||
"description": "Herhangi bir özelliği olmayan yetersiz bir root kullanıcısı."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Root incompetente",
|
||||
"description": "Um usuário root incompetente sem qualquer capacidade."
|
||||
},
|
||||
"ja": {
|
||||
"name": "無能な root",
|
||||
"description": "権限のない root ユーザー。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Root incompetente",
|
||||
"description": "Un utente root senza nessuna capacità."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"id":"kernelmanager.root",
|
||||
"name":"Kernel Manager",
|
||||
"author":"Rem01Gaming",
|
||||
"description":"Commonly used in Kernel managers such as FKM and SmartPack.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"ROOT",
|
||||
"READPROC"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_KILL",
|
||||
"CAP_SYSLOG",
|
||||
"CAP_SYS_BOOT",
|
||||
"CAP_DAC_OVERRIDE"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"namespace":"INHERITED",
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "কার্নেল ম্যানেজার",
|
||||
"description": "এফ কে এম বা স্মার্টপ্যাক কার্নেল ম্যানেজারের যে অনুমতি লাগে।"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "核心管理器",
|
||||
"description": "常用於 FKM 和 SmartPack 等核心管理器"
|
||||
},
|
||||
"in": {
|
||||
"name": "Kernel Manager",
|
||||
"description": "Umumnya digunakan pada Kernel manager seperti FKM dan SmartPack."
|
||||
},
|
||||
"tr": {
|
||||
"name": "Kernel Yöneticisi",
|
||||
"description": "FKM ve SmartPack gibi Kernel Yöneticilerinde yaygın olarak kullanılır."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Gerenciador de Kernel",
|
||||
"description": "Comumente usado em gerenciadores de Kernel como FKM e SmartPack."
|
||||
},
|
||||
"ja": {
|
||||
"name": "Kernel マネージャー",
|
||||
"description": "FKM や SmartPack などの XXX マネージャーでよく使用されます。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Gestore Kernel",
|
||||
"description": "Autorizzazioni comunemente richieste in applicazioni per gestire il Kernel come FKM e SmartPack."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"id": "nethunter.root",
|
||||
"name": "Kali NetHunter",
|
||||
"author": "cachiusa",
|
||||
"description": "Required permissions for Kali NetHunter app to chroot.",
|
||||
"namespace": "INHERITED",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"groups": [
|
||||
"ROOT"
|
||||
],
|
||||
"capabilities": [
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_DAC_READ_SEARCH",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_SYS_PTRACE",
|
||||
"CAP_SYS_ADMIN",
|
||||
"CAP_SETGID"
|
||||
],
|
||||
"context": "u:r:su:s0",
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "কালি নেটহানটার",
|
||||
"description": "কালি নেটহানটার অ্যাপের কার্যকলাপের জন্য যে অনুমতিগুলি লাগে।"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Kali NetHunter",
|
||||
"description": "提供Kali NetHunter使用chroot"
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Kali NetHunter",
|
||||
"description": "Permissões necessárias para o app Kali NetHunter fazer chroot."
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Kali NetHunter",
|
||||
"description": "Autorizzazioni richieste per il chroot dell'applicazione Kali NetHunter."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"id":"rootexploler.root",
|
||||
"name":"Root Explorer",
|
||||
"author":"Rem01Gaming",
|
||||
"description":"File manager with Root capabilities.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"ROOT"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_DAC_READ_SEARCH",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_SYS_ADMIN"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"namespace":"INHERITED",
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "রুট এক্সপ্লোরার",
|
||||
"description": "রুট অনুমতি যুক্ত ফাইল ম্যানেজার।"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Root Explorer",
|
||||
"description": "具有根目錄讀寫權限的檔案管理器"
|
||||
},
|
||||
"in": {
|
||||
"name": "Root Explorer",
|
||||
"description": "File manager dengan kemampuan Root."
|
||||
},
|
||||
"tr": {
|
||||
"name": "Root Dosya Tarayıcı",
|
||||
"description": "Root özelliklerine sahip dosya yöneticisi."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Explorador Root",
|
||||
"description": "Gerenciador de arquivos com recursos root."
|
||||
},
|
||||
"ja": {
|
||||
"name": "Root ブラウザ",
|
||||
"description": "Root 機能を備えたファイル マネージャー。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Gestore file root",
|
||||
"description": "Gestore file con permessi root."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"id":"shizuku.root",
|
||||
"name":"Shizuku Service",
|
||||
"author":"Rem01Gaming & JohnRTitor",
|
||||
"description":"Only essential permissions to start Shizuku service.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"SHELL"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_CHOWN"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"namespace":"INHERITED",
|
||||
"locales": {
|
||||
"zh_TW": {
|
||||
"name": "Shizuku",
|
||||
"description": "只有啟動 Shizuku 服務所需的權限"
|
||||
},
|
||||
"bn": {
|
||||
"name": "শিজুকু সার্ভিস",
|
||||
"description": "শিজুকু চালানোর জন্য শুধু যে অনুমতি গুলি লাগে।"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Shizuku",
|
||||
"description": "Shizuku servisini başlatmak için yalnızca gerekli izinler."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Shizuku",
|
||||
"description": "Apenas permissões essenciais para iniciar o serviço Shizuku."
|
||||
},
|
||||
"ja": {
|
||||
"name": "Shizuku",
|
||||
"description": "Shizuku サービスを開始するために必要な権限のみ。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Shizuku",
|
||||
"description": "Permessi essenziali per avviare il servizio Shizuku."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"id":"system",
|
||||
"author":"kernelsu.org",
|
||||
"name":"System",
|
||||
"description":"The permission level at which the Android system runs without any capability.",
|
||||
"uid":1000,
|
||||
"gid":1000,
|
||||
"groups":[
|
||||
"SYSTEM"
|
||||
],
|
||||
"locales": {
|
||||
"bn": {
|
||||
"name": "সিস্টেম",
|
||||
"description": "অ্যান্ড্রয়েড সিস্টেম যে অনুমতিগুলি নিয়ে কাজ করে।"
|
||||
},
|
||||
"zh_CN": {
|
||||
"name": "Android 系统",
|
||||
"description": "Android 系统运行的权限级别,但没有任何权能。"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Android 系統",
|
||||
"description": "Android 系統運作的權限級別,但沒有任何權能"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Sistem",
|
||||
"description": "Android sisteminin herhangi bir yetenek olmadan çalıştığı izin düzeyi."
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Sistema",
|
||||
"description": "O nível de permissão no qual o sistema Android é executado sem qualquer capacidade."
|
||||
},
|
||||
"ja": {
|
||||
"name": "System",
|
||||
"description": "Android システムが実行される許可レベルですが、機能はありません。"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Sistema",
|
||||
"description": "Il livello di permessi con il quale viene eseguito il sistema operativo Android senza alcuna capacità."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"id":"wireguard.root",
|
||||
"name":"Wireguard kernel module function",
|
||||
"author":"hotfur",
|
||||
"description":"Essential permissions for a working Wireguard kernel module backend. The optional Wireguard command line tools installation requires DAC_OVERRIDE for writing binaries to /system/bin. Because it is optional for operation, DAC_OVERRIDE is not granted here but you can grant the capability temporarily then revoke it after the app installed the command line binaries.",
|
||||
"uid":0,
|
||||
"gid":0,
|
||||
"groups":[
|
||||
"ROOT"
|
||||
],
|
||||
"capabilities":[
|
||||
"CAP_DAC_READ_SEARCH",
|
||||
"CAP_NET_ADMIN",
|
||||
"CAP_NET_RAW"
|
||||
],
|
||||
"context":"u:r:su:s0",
|
||||
"namespace":"INHERITED",
|
||||
}
|
||||
@@ -1,723 +0,0 @@
|
||||
[
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "kernel_xiaomi_sm8250",
|
||||
"kernel_link": "https://github.com/diphons/kernel_xiaomi_sm8250/tree/main",
|
||||
"devices": "Poco F3: alioth | Poco F4: munch | MI10T/PRO: Apollo"
|
||||
},
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "D8G_Kernel_SM8150",
|
||||
"kernel_link": "https://github.com/diphons/D8G_Kernel_SM8150/tree/13",
|
||||
"devices": "Poco X3 Pro: Vayu | Bhima"
|
||||
},
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "kernel_xiaomi_sdm845",
|
||||
"kernel_link": "https://github.com/diphons/kernel_xiaomi_sdm845/tree/main",
|
||||
"devices": "Poco F1"
|
||||
},
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "kernel_xiaomi_sm8350",
|
||||
"kernel_link": "https://github.com/diphons/kernel_xiaomi_sm8350/tree/15",
|
||||
"devices": "MI11T Pro: vili"
|
||||
},
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "D8G_Kernel_Marble",
|
||||
"kernel_link": "https://github.com/diphons/D8G_Kernel_Marble/tree/op",
|
||||
"devices": "Poco F5 | Redmi Note 12 Turbo | Marble"
|
||||
},
|
||||
{
|
||||
"maintainer": "diphons",
|
||||
"maintainer_link": "https://github.com/diphons",
|
||||
"kernel_name": "kernel_xiaomi_sm8635",
|
||||
"kernel_link": "https://github.com/diphons/kernel_xiaomi_sm8635/tree/main",
|
||||
"devices": "Poco F6: peridot"
|
||||
},
|
||||
{
|
||||
"maintainer": "th1nhhdk",
|
||||
"maintainer_link": "https://github.com/th1nhhdk",
|
||||
"kernel_name": "android_kernel_sony_sm8250-kernelsu",
|
||||
"kernel_link": "https://github.com/th1nhhdk/android_kernel_sony_sm8250-kernelsu",
|
||||
"devices": "Sony Xperia 1 II | Sony Xperia 5 II"
|
||||
},
|
||||
{
|
||||
"maintainer": "akash07k",
|
||||
"maintainer_link": "https://github.com/akash07k",
|
||||
"kernel_name": "nexus_kernel_xiaomi_sm8250",
|
||||
"kernel_link": "https://github.com/akash07k/nexus_kernel_xiaomi_sm8250/tree/lychee",
|
||||
"devices": "Poco F4: munch"
|
||||
},
|
||||
{
|
||||
"maintainer": "Hadad",
|
||||
"maintainer_link": "https://xdaforums.com/m/hadad.8351572/",
|
||||
"kernel_name": "android_kernel_xiaomi_onc",
|
||||
"kernel_link": "https://github.com/hadadarjt/android_kernel_xiaomi_onc/tree/los21-KSU/local-non-gerrit-review",
|
||||
"devices": "Redmi 7: onclite | Redmi Y3: onc"
|
||||
},
|
||||
{
|
||||
"maintainer": "HMTheBoy154",
|
||||
"maintainer_link": "https://github.com/hmtheboy154",
|
||||
"kernel_name": "Darkmatter-kernel",
|
||||
"kernel_link": "https://github.com/hmtheboy154/Darkmatter-kernel",
|
||||
"devices": "Generic x86_64 devices running Android-x86"
|
||||
},
|
||||
{
|
||||
"maintainer": "Asuka-mio",
|
||||
"maintainer_link": "https://github.com/asuka-mio",
|
||||
"kernel_name": "android_kernel_xiaomi_cas",
|
||||
"kernel_link": "https://github.com/AcmeUI-Devices/android_kernel_xiaomi_cas",
|
||||
"devices": "Mi 10 Ultra: cas"
|
||||
},
|
||||
{
|
||||
"maintainer": "xiaoleGun",
|
||||
"maintainer_link": "https://github.com/xiaoleGun",
|
||||
"kernel_name": "Miku_kernel_xiaomi_wayne",
|
||||
"kernel_link": "https://github.com/Diva-Room/Miku_kernel_xiaomi_wayne",
|
||||
"devices": "wayne"
|
||||
},
|
||||
{
|
||||
"maintainer": "SakuraNotStupid",
|
||||
"maintainer_link": "https://github.com/SakuraKyuo",
|
||||
"kernel_name": "android_kernel_xiaomi_sdm710",
|
||||
"kernel_link": "https://github.com/SakuraKyuo/android_kernel_xiaomi_sdm710",
|
||||
"devices": "Xiaomi MI 8 SE(sirius/xmsirius)"
|
||||
},
|
||||
{
|
||||
"maintainer": "zlm324",
|
||||
"maintainer_link": "https://github.com/zlm324",
|
||||
"kernel_name": "android_kernel_xiaomi_msm8998",
|
||||
"kernel_link": "https://github.com/zlm324/android_kernel_xiaomi_msm8998_ksu",
|
||||
"devices": "MI 6 (sagit) and MIX 2 (chiron) for LineageOS"
|
||||
},
|
||||
{
|
||||
"maintainer": "SlackerState",
|
||||
"maintainer_link": "https://github.com/SlackerState",
|
||||
"kernel_name": "android_kernel_xiaomi_sm6150",
|
||||
"kernel_link": "https://github.com/SlackerState/android_kernel_xiaomi_sm6150",
|
||||
"devices": "Redmi K30 4G (phoenix)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RooGhz720",
|
||||
"maintainer_link": "https://github.com/RooGhz720",
|
||||
"kernel_name": "kernel_xiaomi_sm6150",
|
||||
"kernel_link": "https://github.com/RooGhz720/kernel_xiaomi_sm6150",
|
||||
"devices": "REDMI NOTE 10 PRO (sweet)"
|
||||
},
|
||||
{
|
||||
"maintainer": "OnlyTomInSecond",
|
||||
"maintainer_link": "https://github.com/onlyTomInSecond/",
|
||||
"kernel_name": "android_kernel_xiaomi_sdm845",
|
||||
"kernel_link": "https://github.com/OnlyTomInSecond/android_kernel_xiaomi_sdm845",
|
||||
"devices": "Mi 8 (dipper) for LineageOS"
|
||||
},
|
||||
{
|
||||
"maintainer": "Rohail33",
|
||||
"maintainer_link": "https://github.com/Rohail33",
|
||||
"kernel_name": "RealKing Kernel",
|
||||
"kernel_link": "https://github.com/Rohail33/Realking_kernel_sm8250",
|
||||
"devices": "Apollo(Redmi K30S Ultra/Mi 10T/Mi 10T Pro)\uff0cAlioth(Redmi K40/POCO F3/Mi 11X)\uff0cMunch(Redmi K40S/POCO F4), both MIUI and AOSP."
|
||||
},
|
||||
{
|
||||
"maintainer": "Sreeshankar K",
|
||||
"maintainer_link": "https://github.com/sreeshankark",
|
||||
"kernel_name": "NeverSettle Kernel",
|
||||
"kernel_link": "https://github.com/sreeshankark/android_kernel_oneplus_avicii",
|
||||
"devices": "OnePlus Nord (avicii)"
|
||||
},
|
||||
{
|
||||
"maintainer": "PSavarMattas",
|
||||
"maintainer_link": "https://github.com/psavarmattas",
|
||||
"kernel_name": "PSM Kernel",
|
||||
"kernel_link": "https://github.com/psavarmattas/android_kernel_oneplus_sm7250-WKSU",
|
||||
"devices": "OnePlus Nord (avicii)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Molyuu",
|
||||
"maintainer_link": "https://github.com/Molyuu",
|
||||
"kernel_name": "neko_kernel_xiaomi_gauguin",
|
||||
"kernel_link": "https://github.com/Molyuu/neko_kernel_xiaomi_gauguin",
|
||||
"devices": "Redmi Note 9 Pro/ Mi 10T Lite/ Mi 10i "
|
||||
},
|
||||
{
|
||||
"maintainer": "guh0613",
|
||||
"maintainer_link": "https://github.com/guh0613",
|
||||
"kernel_name": "android_kernel_oppo_sm8150",
|
||||
"kernel_link": "https://github.com/guh0613/android_kernel_oppo_sm8150",
|
||||
"devices": "OPPO Reno Ace (OP4A89)"
|
||||
},
|
||||
{
|
||||
"maintainer": "LeviMarvin",
|
||||
"maintainer_link": "https://github.com/LeviMarvin",
|
||||
"kernel_name": "android_kernel_xiaomi_alioth",
|
||||
"kernel_link": "https://github.com/LeviMarvin/android_kernel_xiaomi_alioth",
|
||||
"devices": "Redmi K40 / POCO F3"
|
||||
},
|
||||
{
|
||||
"maintainer": "cibimo",
|
||||
"maintainer_link": "https://github.com/cibimo",
|
||||
"kernel_name": "kernel_xiaomi_raphael_ksu",
|
||||
"kernel_link": "https://github.com/cibimo/kernel_xiaomi_raphael_ksu",
|
||||
"devices": "Xiaomi Redmi K20 Pro / Mi 9T Pro (raphael)"
|
||||
},
|
||||
{
|
||||
"maintainer": "EndCredits",
|
||||
"maintainer_link": "https://github.com/EndCredits",
|
||||
"kernel_name": "kernel_xiaomi_sm7250",
|
||||
"kernel_link": "https://github.com/EndCredits/kernel_xiaomi_sm7250",
|
||||
"devices": "Redmi K30 5G ( picasso ) , Redmi K30i 5G ( picasso_48m)"
|
||||
},
|
||||
{
|
||||
"maintainer": "msnx",
|
||||
"maintainer_link": "https://github.com/msnx",
|
||||
"kernel_name": "android-msm-coral-4.14-android13",
|
||||
"kernel_link": "https://github.com/msnx/KernelSU-Pixel4XL",
|
||||
"devices": "Pixel 4 XL"
|
||||
},
|
||||
{
|
||||
"maintainer": "SoDebug",
|
||||
"maintainer_link": "https://github.com/SoDebug",
|
||||
"kernel_name": "kernel_xiaomi_raphael",
|
||||
"kernel_link": "https://github.com/SoDebug/KernelSU_Kernel_Raphael",
|
||||
"devices": "Xiaomi Redmi K20 Pro / Mi 9T Pro (raphael)"
|
||||
},
|
||||
{
|
||||
"maintainer": "H1mJT",
|
||||
"maintainer_link": "https://github.com/H1mJT",
|
||||
"kernel_name": "kernel_realme_RMX1901",
|
||||
"kernel_link": "https://github.com/H1mJT/kernel_realme_RMX1901",
|
||||
"devices": "Realme X (RMX1901/RMX1901CN)"
|
||||
},
|
||||
{
|
||||
"maintainer": "SonalSingh18",
|
||||
"maintainer_link": "https://github.com/SonalSingh18",
|
||||
"kernel_name": "android_kernel_xiaomi_sm6250",
|
||||
"kernel_link": "https://github.com/SonalSingh18/android_kernel_xiaomi_sm6250",
|
||||
"devices": "Miatoll [curtana, excalibur, gram, joyeuse]"
|
||||
},
|
||||
{
|
||||
"maintainer": "RooGhz720",
|
||||
"maintainer_link": "https://github.com/RooGhz720",
|
||||
"kernel_name": "kernel_xiaomi_lavender",
|
||||
"kernel_link": "https://github.com/RooGhz720/kernel_xiaomi_lavender",
|
||||
"devices": "Redmi Note 7 (Lavender)"
|
||||
},
|
||||
{
|
||||
"maintainer": "JunASAKA",
|
||||
"maintainer_link": "https://github.com/JunASAKA",
|
||||
"kernel_name": "kernel_google_msm-4.9_KernelSU",
|
||||
"kernel_link": "https://github.com/JunASAKA/kernel_google_msm-4.9_KernelSU",
|
||||
"devices": "Google Pixel 3a & 3a XL (sargo & bonito)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RooGhz720",
|
||||
"maintainer_link": "https://github.com/RooGhz720",
|
||||
"kernel_name": "kernel_asus_X01BD",
|
||||
"kernel_link": "https://github.com/RooGhz720/kernel_asus_X01BD",
|
||||
"devices": "Asus Zenfone Max Pro M1/M2"
|
||||
},
|
||||
{
|
||||
"maintainer": "Evans Mike",
|
||||
"maintainer_link": "https://github.com/etnperlong",
|
||||
"kernel_name": "kernel_xiaomi_raphael_bool-x",
|
||||
"kernel_link": "https://github.com/etnperlong/kernel_xiaomi_raphael_bool-x",
|
||||
"devices": "Xiaomi Redmi K20 Pro / Mi 9T Pro (raphael)"
|
||||
},
|
||||
{
|
||||
"maintainer": "easterNday",
|
||||
"maintainer_link": "https://github.com/DogDayAndroid",
|
||||
"kernel_name": "KSU_Thyme_BuildBot",
|
||||
"kernel_link": "https://github.com/DogDayAndroid/KSU_Thyme_BuildBot",
|
||||
"devices": "Xiaomi 10S"
|
||||
},
|
||||
{
|
||||
"maintainer": "tedomi2705",
|
||||
"maintainer_link": "https://github.com/tedomi2705",
|
||||
"kernel_name": "kernel_xiaomi_sdm660",
|
||||
"kernel_link": "https://github.com/tedomi2705/kernel_xiaomi_sdm660",
|
||||
"devices": "Xiaomi Redmi Note 6 Pro (tulip)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RyuujiX",
|
||||
"maintainer_link": "https://github.com/RyuujiX",
|
||||
"kernel_name": "android_kernel_asus_sdm660-4.19",
|
||||
"kernel_link": "https://github.com/RyuujiX/android_kernel_asus_sdm660-4.19",
|
||||
"devices": "Asus Zenfone Max Pro M1 (X00TD)/ M2 (X01BD) (Linux 4.19)"
|
||||
},
|
||||
{
|
||||
"maintainer": "liqidecg",
|
||||
"maintainer_link": "https://github.com/liqidecg",
|
||||
"kernel_name": "android_kernel_xiaomi_sdm710",
|
||||
"kernel_link": "https://github.com/liqidecg/android_kernel_xiaomi_sdm710",
|
||||
"devices": "Mi 8 SE (sirius) (Linux 4.9)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Abdelhay-Ali",
|
||||
"maintainer_link": "https://github.com/Abdelhay-Ali",
|
||||
"kernel_name": "android_kernel_huawei_hi6250",
|
||||
"kernel_link": "https://github.com/Abdelhay-Ali/android_kernel_huawei_hi6250_KernelSU",
|
||||
"devices": "Huawei P20 lite (hi6250) (Linux 4.9)"
|
||||
},
|
||||
{
|
||||
"maintainer": "reocat",
|
||||
"maintainer_link": "https://github.com/reocat",
|
||||
"kernel_name": "android_kernel_nokia_sdm660_ksu",
|
||||
"kernel_link": "https://github.com/reocat/android_kernel_nokia_sdm660_ksu",
|
||||
"devices": "Nokia 6.1 (2018)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Tuan Anh",
|
||||
"maintainer_link": "https://github.com/log1cs",
|
||||
"kernel_name": "kernel_nokia_msm8998",
|
||||
"kernel_link": "https://github.com/log1cs/kernel_nokia_msm8998",
|
||||
"devices": "Nokia 8 (Repartitioned)/8 Sirocco (NLA/A1N)"
|
||||
},
|
||||
{
|
||||
"maintainer": "bggRGjQaUbCoE",
|
||||
"maintainer_link": "https://github.com/bggRGjQaUbCoE",
|
||||
"kernel_name": "android_kernel_samsung_sm8250",
|
||||
"kernel_link": "https://github.com/bggRGjQaUbCoE/android_kernel_samsung_sm8250-mohammad92",
|
||||
"devices": "Samsung Galaxy S20+ 5G (y2q)"
|
||||
},
|
||||
{
|
||||
"maintainer": "SOVIET-ANDROID",
|
||||
"maintainer_link": "https://github.com/SOVIET-ANDROID",
|
||||
"kernel_name": "kernel_xiaomi_raphael",
|
||||
"kernel_link": "https://github.com/SOVIET-ANDROID/kernel_xiaomi_raphael",
|
||||
"devices": "XK20 Pro Raphael DSP & A only SAR support "
|
||||
},
|
||||
{
|
||||
"maintainer": "dabao1955",
|
||||
"maintainer_link": "https://github.com/dabao1955",
|
||||
"kernel_name": "android_kernel_OPPO_PEQM00",
|
||||
"kernel_link": "https://github.com/dabao1955/android_kernel_OPPO_PEQM00",
|
||||
"devices": "MediaTek devices in the OPPO Reno series on ColorOS13.x"
|
||||
},
|
||||
{
|
||||
"maintainer": "Aflaungos",
|
||||
"maintainer_link": "https://github.com/Aflaungos",
|
||||
"kernel_name": "android_kernel_motorola_msm8998",
|
||||
"kernel_link": "https://github.com/Aflaungos/android_kernel_motorola_msm8998",
|
||||
"devices": "Moto G6 Plus (evert)"
|
||||
},
|
||||
{
|
||||
"maintainer": "TheNoFace",
|
||||
"maintainer_link": "https://github.com/TheNoFace",
|
||||
"kernel_name": "kernel_oneplus_msm8998",
|
||||
"kernel_link": "https://github.com/TheNoFace/kernel_oneplus_msm8998/tree/pe-13-ksu",
|
||||
"devices": "OnePlus 5/5T (cheeseburger/dumpling)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Nipin NA (Joker-V2)",
|
||||
"maintainer_link": "https://github.com/Joker-V2",
|
||||
"kernel_name": "Xcalibur kernel (violet)",
|
||||
"kernel_link": "https://github.com/Joker-V2/kernel_xiaomi_violet/tree/kernelsu",
|
||||
"devices": "Xiaomi Redmi Note 7 Pro (violet)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Sr-Han",
|
||||
"maintainer_link": "https://github.com/Sr-Han",
|
||||
"kernel_name": "kernel_xiaomi_mojito",
|
||||
"kernel_link": "https://github.com/Sr-Han/kernel_xiaomi_mojito",
|
||||
"devices": "Redmi Note 10 (Sunny/Mojito)"
|
||||
},
|
||||
{
|
||||
"maintainer": "rushiranpise",
|
||||
"maintainer_link": "https://github.com/rushiranpise",
|
||||
"kernel_name": "android_kernel_samsung_exynos9610_mint",
|
||||
"kernel_link": "https://github.com/rushiranpise/android_kernel_samsung_exynos9610_mint",
|
||||
"devices": "Kernel 4.14.194 exynos9610 Non-GKI Device, Added KernelSu using manual method"
|
||||
},
|
||||
{
|
||||
"maintainer": "CN-Scars",
|
||||
"maintainer_link": "https://github.com/CN-Scars",
|
||||
"kernel_name": "pixel_experience_kernel_xiaomi_sm8250_kernelSU",
|
||||
"kernel_link": "https://github.com/CN-Scars/pixel_experience_kernel_xiaomi_sm8250_kernelSU",
|
||||
"devices": "Pixel Experience Kernel 4.19.282 for Xiaomi Redmi K40S / Xiaomi Poco F4 (munch)"
|
||||
},
|
||||
{
|
||||
"maintainer": "exer",
|
||||
"maintainer_link": "https://github.com/ekkusa",
|
||||
"kernel_name": "Miyo Toku",
|
||||
"kernel_link": "https://github.com/Miiyo/android_kernel_sony_sdm845/tree/KSU/Toku",
|
||||
"devices": "Sony Tama (akari, apollo, aurora, akatsuki) (Linux 4.9)"
|
||||
},
|
||||
{
|
||||
"maintainer": "likkai",
|
||||
"maintainer_link": "https://github.com/likkai",
|
||||
"kernel_name": "Quicksilver Kernel",
|
||||
"kernel_link": "https://github.com/likkai/ksu_kernel_xiaomi_lisa",
|
||||
"devices": "Xiaomi 11 Lite 5G NE (lisa)"
|
||||
},
|
||||
{
|
||||
"maintainer": "awakened1712",
|
||||
"maintainer_link": "https://github.com/awakened1712",
|
||||
"kernel_name": "android_kernel_samsung_exynos9820",
|
||||
"kernel_link": "https://github.com/awakened1712/android_kernel_samsung_exynos9820",
|
||||
"devices": "Samsung S10/N10"
|
||||
},
|
||||
{
|
||||
"maintainer": "awakened1712",
|
||||
"maintainer_link": "https://github.com/awakened1712",
|
||||
"kernel_name": "android_kernel_oneplus_sm8350",
|
||||
"kernel_link": "https://github.com/awakened1712/android_kernel_oneplus_sm8350",
|
||||
"devices": "Oneplus 9/9Pro"
|
||||
},
|
||||
{
|
||||
"maintainer": "siimsek",
|
||||
"maintainer_link": "https://github.com/siimsek",
|
||||
"kernel_name": "Lightning Kernel",
|
||||
"kernel_link": "https://github.com/siimsek/Lightning-Kernel",
|
||||
"devices": "Xiaomi Redmi Note 8/8T (ginkgo/willow)"
|
||||
},
|
||||
{
|
||||
"maintainer": "GiovanYCringe",
|
||||
"maintainer_link": "https://github.com/GiovanYCringe",
|
||||
"kernel_name": "kernel_a50",
|
||||
"kernel_link": "https://github.com/GiovanYCringe-Experiments/kernel_a50",
|
||||
"devices": "Galaxy A50 (A505f,fn,g,gn,gt)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Asriadi Rahim",
|
||||
"maintainer_link": "https://github.com/asriadirahim",
|
||||
"kernel_name": "android_kernel_google_wahoo",
|
||||
"kernel_link": "https://github.com/Google-Pixel2-2XL/kernel_google_wahoo",
|
||||
"devices": "Google Pixel 2/2XL"
|
||||
},
|
||||
{
|
||||
"maintainer": "DawfukFR",
|
||||
"maintainer_link": "https://github.com/DawfukFR",
|
||||
"kernel_name": "kernel_oneplus_sm8250 (Stellaris-Kernel)",
|
||||
"kernel_link": "https://github.com/DawfukFR/kernel_oneplus_sm8250",
|
||||
"devices": "Oneplus 8 (Instantnoodle), Oneplus 8T (Kebab), Oneplus 8 Pro (Instantnoodlep), Oneplus 9R (lemonades) [msm-4.19]"
|
||||
},
|
||||
{
|
||||
"maintainer": "Tejas Singh",
|
||||
"maintainer_link": "https://github.com/tejas101k",
|
||||
"kernel_name": "kernel_xiaomi_ginkgo (Cuh Kernel)",
|
||||
"kernel_link": "https://github.com/tejas101k/Cuh-KerneL",
|
||||
"devices": "Xiaomi Redmi Note 8/8T (ginkgo/willow)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Abdul Wahid Khan",
|
||||
"maintainer_link": "https://github.com/Wahid7852",
|
||||
"kernel_name": "kernel_xiaomi_begonia",
|
||||
"kernel_link": "https://github.com/Nova-Kernels/kernel_xiaomi_mt6785",
|
||||
"devices": "Redmi Note 8 Pro (Begonia/Begoniain)"
|
||||
},
|
||||
{
|
||||
"maintainer": "zfdx123",
|
||||
"maintainer_link": "https://github.com/zfdx123",
|
||||
"kernel_name": "kernel_xiaomi_alioth",
|
||||
"kernel_link": "https://github.com/zfdx123/kernel_xiaomi_alioth",
|
||||
"devices": "Redmi K40 (alioth)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Bot-wxt1221",
|
||||
"maintainer_link": "https://github.com/Bot-wxt1221",
|
||||
"kernel_name": "android_kernel_oneplus_sdm845",
|
||||
"kernel_link": "https://github.com/Bot-wxt1221/android_kernel_oneplus_sdm845",
|
||||
"devices": "Oneplus 6 (enchilada) | Oneplus 6T (fajita) with Retrofit Dynamic Partitions Only with crdroid"
|
||||
},
|
||||
{
|
||||
"maintainer": "zlm324",
|
||||
"maintainer_link": "https://github.com/zlm324",
|
||||
"kernel_name": "android_kernel_xiaomi_msm8998_ksu",
|
||||
"kernel_link": "https://github.com/zlm324/android_kernel_xiaomi_msm8998_ksu",
|
||||
"devices": "a lineage kernel forked from LineageOS official repository, version 4.4.302, added ksu."
|
||||
},
|
||||
{
|
||||
"maintainer": "zlm324",
|
||||
"maintainer_link": "https://github.com/zlm324",
|
||||
"kernel_name": "android_kernel_xiaomi_msm8953_ksu",
|
||||
"kernel_link": "https://github.com/zlm324/android_kernel_xiaomi_msm8953_ksu",
|
||||
"devices": "Xiaomi 5X (tiffany)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Vincent4440",
|
||||
"maintainer_link": "https://github.com/Vincent4440",
|
||||
"kernel_name": "android_kernel_xiaomi_sm8250",
|
||||
"kernel_link": "https://github.com/Vincent4440/android_kernel_xiaomi_sm8250",
|
||||
"devices": "Poco F4: munch"
|
||||
},
|
||||
{
|
||||
"maintainer": "tiandoufayale",
|
||||
"maintainer_link": "https://github.com/tiandoufayale",
|
||||
"kernel_name": "android_kernel_samsung_sm8250",
|
||||
"kernel_link": "https://github.com/tiandoufayale/android_kernel_samsung_sm8250",
|
||||
"devices": "Samsung Tab S7 WIFI(T870)"
|
||||
},
|
||||
{
|
||||
"maintainer": "starmoe",
|
||||
"maintainer_link": "https://github.com/bro-xun",
|
||||
"kernel_name": "android_kernel_oneplus_msm8998",
|
||||
"kernel_link": "https://github.com/Bro-Xun/kernel_op5t_ksu",
|
||||
"devices": "Oneplus 5/5T, kernel version 4.4.302"
|
||||
},
|
||||
{
|
||||
"maintainer": "supechicken",
|
||||
"maintainer_link": "https://github.com/supechicken",
|
||||
"kernel_name": "kernel_xiaomi_sm8350",
|
||||
"kernel_link": "https://github.com/supechicken/kernel_xiaomi_sm8350",
|
||||
"devices": " Xiaomi 11T Pro (vili)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Vaz15k",
|
||||
"maintainer_link": "https://github.com/Vaz15k",
|
||||
"kernel_name": "kernelSU-A70q",
|
||||
"kernel_link": "https://github.com/Vaz15k/kernelSU-A70q",
|
||||
"devices": "Samsung Galaxy A70 ( A705MN / A705FN )"
|
||||
},
|
||||
{
|
||||
"maintainer": "whyakari",
|
||||
"maintainer_link": "https://github.com/whyakari",
|
||||
"kernel_name": "android_kernel_xiaomi_ginkgo",
|
||||
"kernel_link": "https://github.com/whyakari/android_kernel_xiaomi_ginkgo",
|
||||
"devices": "Xiaomi Redmi Note 8/8T (ginkgo/willow)"
|
||||
},
|
||||
{
|
||||
"maintainer": "wulan17",
|
||||
"maintainer_link": "https://github.com/wulan17",
|
||||
"kernel_name": "android_kernel_xiaomi_mt6765",
|
||||
"kernel_link": "https://github.com/Mayuri-Chan/android_kernel_xiaomi_mt6765/tree/10-ksu",
|
||||
"devices": "Redmi 6/6A (cereus/cactus)"
|
||||
},
|
||||
{
|
||||
"maintainer": "officialputuid",
|
||||
"maintainer_link": "https://github.com/officialputuid",
|
||||
"kernel_name": "android_kernel_realme_mt6785",
|
||||
"kernel_link": "https://github.com/psionicprjkt/android_kernel_realme_mt6785",
|
||||
"devices": "Realme 6/6i(Indian)/6s/7/Narzo/Narzo 20 Pro/Narzo 30 4G (RM6785)"
|
||||
},
|
||||
{
|
||||
"maintainer": "liquidprjkt",
|
||||
"maintainer_link": "https://github.com/liquidprjkt",
|
||||
"kernel_name": "liquid_kernel_realme_even",
|
||||
"kernel_link": "https://github.com/liquidprjkt/liquid_kernel_realme_even",
|
||||
"devices": "Realme C25/s and Narzo50A (even)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Tonklaistonton",
|
||||
"maintainer_link": "https://github.com/Tonklaistonton",
|
||||
"kernel_name": "NEXGatokernel",
|
||||
"kernel_link": "https://github.com/Tonklaistonton/android_kernel_oneplus_sm6375",
|
||||
"devices": "Realme 9 pro 5g | Oneplus nord ce 2 lite "
|
||||
},
|
||||
{
|
||||
"maintainer": "CoolestEnoch",
|
||||
"maintainer_link": "https://github.com/CoolestEnoch",
|
||||
"kernel_name": "kernel-su-huawei-nova2",
|
||||
"kernel_link": "https://github.com/CoolestEnoch/kernel-su-huawei-nova2",
|
||||
"devices": "Huawei nova 2 (pic)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RisenID",
|
||||
"maintainer_link": "https://github.com/RisenID",
|
||||
"kernel_name": "kernel_samsung_ascendia_sm7325",
|
||||
"kernel_link": "https://github.com/RisenID/kernel_samsung_ascendia_sm7325",
|
||||
"devices": "Samsung Galaxy A52s 5G (a52sxq)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RisenID",
|
||||
"maintainer_link": "https://github.com/RisenID",
|
||||
"kernel_name": "kernel_samsung_ascendia_sm7125",
|
||||
"kernel_link": "https://github.com/RisenID/kernel_samsung_ascendia_sm7125",
|
||||
"devices": "Samsung Galaxy A52 4G (a52q)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RisenID",
|
||||
"maintainer_link": "https://github.com/RisenID",
|
||||
"kernel_name": "kernel_samsung_ascendia_sm7125",
|
||||
"kernel_link": "https://github.com/RisenID/kernel_samsung_ascendia_sm7125",
|
||||
"devices": "Samsung Galaxy A72 (a72q)"
|
||||
},
|
||||
{
|
||||
"maintainer": "RisenID",
|
||||
"maintainer_link": "https://github.com/RisenID",
|
||||
"kernel_name": "kernel_samsung_ascendia_sm7325",
|
||||
"kernel_link": "https://github.com/RisenID/kernel_samsung_ascendia_sm7325",
|
||||
"devices": "Samsung Galaxy M52 5G (m52xq)"
|
||||
},
|
||||
{
|
||||
"maintainer": "A-JiuA",
|
||||
"maintainer_link": "https://github.com/A-JiuA",
|
||||
"kernel_name": "sirius_Kernel",
|
||||
"kernel_link": "https://github.com/A-JiuA/sirius_Kernel",
|
||||
"devices": "Xiaomi MI 8 SE(MIUI12/12.5)"
|
||||
},
|
||||
{
|
||||
"maintainer": "picasso09",
|
||||
"maintainer_link": "https://github.com/picasso09",
|
||||
"kernel_name": "KernelSU-RM6765R",
|
||||
"kernel_link": "https://github.com/picasso09/RMX2189R/tree/c05-ksu",
|
||||
"devices": "Realme C11 12 15 (RM6765)"
|
||||
},
|
||||
{
|
||||
"maintainer": "josedelinux",
|
||||
"maintainer_link": "https://github.com/josedelinux",
|
||||
"kernel_name": "kernel_google_msm-4.9",
|
||||
"kernel_link": "https://github.com/josedelinux/kernel_google_msm-4.9",
|
||||
"devices": "Google Pixel 3a & 3a XL (sargo & bonito)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Lonelystar9x",
|
||||
"maintainer_link": "https://github.com/lonelystar9x",
|
||||
"kernel_name": "Kernel_xiaomi_sdm845",
|
||||
"kernel_link": "https://github.com/lonelystar9x/android_kernel_xiaomi_sdm845",
|
||||
"devices": "Poco F1 | MI8 | MiMix2S | MiMix3"
|
||||
},
|
||||
{
|
||||
"maintainer": "iceBear67",
|
||||
"maintainer_link": "https://github.com/iceBear67",
|
||||
"kernel_name": "android_kernel_exynos9810_kernelsu",
|
||||
"kernel_link": "https://github.com/iceBear67/android_kernel_exynos9810_kernelsu",
|
||||
"devices": "Galaxy Note 9(N960N/F)"
|
||||
},
|
||||
{
|
||||
"maintainer": "BlackMesa123",
|
||||
"maintainer_link": "https://xdaforums.com/t/kernel-a546b-e-kernelsu-v0-7-5-for-galaxy-a54-5g.4607539/",
|
||||
"kernel_name": "android_kernel_samsung_s5e8835",
|
||||
"kernel_link": "https://github.com/BlackMesa123/android_kernel_samsung_s5e8835",
|
||||
"devices": "Samsung Galaxy A54 5G (a54x)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Fede2782",
|
||||
"maintainer_link": "https://github.com/Fede2782",
|
||||
"kernel_name": "android_kernel_samsung_a34x",
|
||||
"kernel_link": "https://github.com/Fede2782/android_kernel_samsung_a34x/",
|
||||
"devices": "Samsung Galaxy A34 5G (a34x)"
|
||||
},
|
||||
{
|
||||
"maintainer": "SnowWolf725 ",
|
||||
"maintainer_link": "https://github.com/snowwolf725",
|
||||
"kernel_name": "android_kernel_oneplus_sm8150",
|
||||
"kernel_link": "https://github.com/snowwolf725/android_kernel_oneplus_sm8150",
|
||||
"devices": "Oneplus 7(guacamoleb)/7 Pro(guacamole)/7T(hotdog)/7TPro (hotdogb)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Fede2782",
|
||||
"maintainer_link": "https://github.com/Fede2782",
|
||||
"kernel_name": "android_kernel_samsung_gta4xl",
|
||||
"kernel_link": "https://github.com/Fede2782/android_kernel_samsung_gta4xl",
|
||||
"devices": "Galaxy Tab S6 Lite LTE (gta4xl)"
|
||||
},
|
||||
{
|
||||
"maintainer": "ArchVisions",
|
||||
"maintainer_link": "https://github.com/ArchVisions",
|
||||
"kernel_name": "android_kernel_samsung_gts9fewifi",
|
||||
"kernel_link": "https://github.com/ArchVisions/android_kernel_samsung_gts9fewifi",
|
||||
"devices": "Samsung Tab S9 FE (gts9fewifi) | Exynos 1380"
|
||||
},
|
||||
{
|
||||
"maintainer": "ravindu644",
|
||||
"maintainer_link": "https://github.com/ravindu644",
|
||||
"kernel_name": "android_kernel_beyondx_lpos",
|
||||
"kernel_link": "https://github.com/ravindu644/android_kernel_beyondx_lpos",
|
||||
"devices": "Galaxy S10 5G (KOR)"
|
||||
},
|
||||
{
|
||||
"maintainer": "ravindu644",
|
||||
"maintainer_link": "https://github.com/ravindu644",
|
||||
"kernel_name": "android_kernel_beyond1_lpos",
|
||||
"kernel_link": "https://github.com/ravindu644/android_kernel_beyond1_lpos",
|
||||
"devices": "Galaxy S10"
|
||||
},
|
||||
{
|
||||
"maintainer": "ravindu644",
|
||||
"maintainer_link": "https://github.com/ravindu644",
|
||||
"kernel_name": "android_kernel_beyond2",
|
||||
"kernel_link": "https://github.com/ravindu644/android_kernel_beyond2",
|
||||
"devices": "Galaxy S10+"
|
||||
},
|
||||
{
|
||||
"maintainer": "ravindu644",
|
||||
"maintainer_link": "https://github.com/ravindu644",
|
||||
"kernel_name": "android_kernel_beyond0",
|
||||
"kernel_link": "https://github.com/ravindu644/android_kernel_beyond0",
|
||||
"devices": "Galaxy S10e"
|
||||
},
|
||||
{
|
||||
"maintainer": "Rofikkernel",
|
||||
"maintainer_link": "https://github.com/Rofikkernel",
|
||||
"kernel_name": "kernel_lgv600tm_4.19",
|
||||
"kernel_link": "https://github.com/Rofikkernel/kernel_lgv600tm_4.19",
|
||||
"devices": "LG V60 timelm"
|
||||
},
|
||||
{
|
||||
"maintainer": "Dawid2849",
|
||||
"maintainer_link": "https://github.com/Dawid2849",
|
||||
"kernel_name": "android_kernel_lge_sm8150",
|
||||
"kernel_link": "https://github.com/Dawid2849/android_kernel_lge_sm8150",
|
||||
"devices": "LG G8 (alphaplus) / LG G8s (betalm) / LG G8X (mh2mml)"
|
||||
},
|
||||
{
|
||||
"maintainer": "lyc8503",
|
||||
"maintainer_link": "https://github.com/lyc8503",
|
||||
"kernel_name": "kernel_xiaomi_chopin",
|
||||
"kernel_link": "https://github.com/ChopinKernels/kernel_xiaomi_chopin_android_S",
|
||||
"devices": "Redmi Note 10 Pro 5G (chopin) / Poco X3 GT (choping)"
|
||||
},
|
||||
{
|
||||
"maintainer": "Fede2782",
|
||||
"maintainer_link": "https://github.com/Fede2782",
|
||||
"kernel_name": "android_kernel_motorola_sdm632",
|
||||
"kernel_link": "https://github.com/Fede2782/android_kernel_motorola_sdm632",
|
||||
"devices": "Motorola Moto G7 (river)"
|
||||
},
|
||||
{
|
||||
"maintainer": "EmanuelCN",
|
||||
"maintainer_link": "https://github.com/EmanuelCN",
|
||||
"kernel_name": "N0Kernel",
|
||||
"kernel_link": "https://github.com/EmanuelCN/kernel_xiaomi_sm8250",
|
||||
"devices": "Poco F3 (alioth) | Mi 10T/Pro (apollo) | Poco F4 (munch)"
|
||||
},
|
||||
{
|
||||
"maintainer": "kvsnr113",
|
||||
"maintainer_link": "https://github.com/kvsnr113",
|
||||
"kernel_name": "NOVA Kernel",
|
||||
"kernel_link": "https://github.com/kvsnr113/xiaomi_sm8250_kernel",
|
||||
"devices": "Poco F3 (alioth) | Mi 10T/Pro (apollo) | Poco F4 (munch)"
|
||||
},
|
||||
{
|
||||
"maintainer": "anVzdGFtb25",
|
||||
"maintainer_link": "https://github.com/anVzdGFtb25",
|
||||
"kernel_name": "android_kernel_xiaomi_mt6768",
|
||||
"kernel_link": "https://github.com/anVzdGFtb25/android_kernel_xiaomi_mt6768",
|
||||
"devices": "Redmi 9 ( lancelot )"
|
||||
},
|
||||
{
|
||||
"maintainer": "rifsxd",
|
||||
"maintainer_link": "https://github.com/rifsxd",
|
||||
"kernel_name": "android_kernel_realme_RMX3511",
|
||||
"kernel_link": "https://github.com/rifsxd/android_kernel_realme_RMX3511",
|
||||
"devices": "Realme C35 (RMX3511)"
|
||||
},
|
||||
{
|
||||
"maintainer": "qlAD",
|
||||
"maintainer_link": "https://github.com/qlAD",
|
||||
"kernel_name": "kernel_oneplus_sdm845",
|
||||
"kernel_link": "https://github.com/qlAD/kernel_oneplus_sdm845",
|
||||
"devices": "OnePlus 6 (enchilada) with PixelExperience "
|
||||
},
|
||||
{
|
||||
"maintainer": "rsuntkOrgs",
|
||||
"maintainer_link": "https://github.com/rsuntkOrgs",
|
||||
"kernel_name": "android_kernel_samsung_a05",
|
||||
"kernel_link": "https://github.com/rsuntkOrgs/android_kernel_samsung_a05",
|
||||
"devices": "Samsung Galaxy A05 (a05m) | SM-A055F/M | MT6768"
|
||||
},
|
||||
{
|
||||
"maintainer": "itejo443",
|
||||
"maintainer_link": "https://github.com/itejo443",
|
||||
"kernel_name": "android_kernel_samsung_sm7225",
|
||||
"kernel_link": "https://github.com/itejo443/android_kernel_samsung_sm7225",
|
||||
"devices": "Samsung Galaxy F23 and M23 (m23xq)"
|
||||
}
|
||||
]
|
||||
@@ -1,118 +0,0 @@
|
||||
# Профиль приложений
|
||||
|
||||
Профиль приложений - это механизм, предоставляемый KernelSU для настройки конфигурации различных приложений.
|
||||
|
||||
Для приложений, получивших права root (т.е. имеющих возможность использовать `su`), App Profile может также называться Root Profile. Он позволяет настраивать правила `uid`, `gid`, `groups`, `capabilities` и `SELinux` команды `su`, тем самым ограничивая привилегии пользователя root. Например, она может предоставлять сетевые права только приложениям межсетевого экрана, отказывая в праве доступа к файлам, или предоставлять права shell вместо полного root-доступа для приложений freeze: **сохранение власти в рамках принципа наименьших привилегий*.
|
||||
|
||||
Для обычных приложений, не имеющих прав root, App Profile может управлять поведением ядра и системы модулей по отношению к этим приложениям. Например, он может определять, следует ли обращать внимание на модификации, возникающие в результате работы модулей. На основе этой конфигурации ядро и система модулей могут принимать решения, например, выполнять операции, аналогичные "скрытию".
|
||||
|
||||
## Корневой профиль
|
||||
|
||||
### UID, GID и группы
|
||||
|
||||
В системах Linux существуют два понятия: пользователи и группы. Каждый пользователь имеет идентификатор пользователя (UID), а пользователь может принадлежать к нескольким группам, каждая из которых имеет свой идентификатор группы (GID). Эти идентификаторы используются для идентификации пользователей в системе и определяют, к каким системным ресурсам они могут получить доступ.
|
||||
|
||||
Пользователи с UID, равным 0, называются корневыми пользователями, а группы с GID, равным 0, - корневыми группами. Группа пользователей root, как правило, обладает самыми высокими системными привилегиями.
|
||||
|
||||
В случае системы Android каждое приложение является отдельным пользователем (исключая сценарии с общим UID) с уникальным UID. Например, `0` представляет пользователя root, `1000` - `system`, `2000` - ADB shell, а UID в диапазоне от 10000 до 19999 - обычные приложения.
|
||||
|
||||
:::info
|
||||
Здесь упомянутый UID не совпадает с концепцией нескольких пользователей или рабочих профилей в системе Android. На самом деле рабочие профили реализуются путем разделения диапазона UID. Например, 10000-19999 представляет собой основного пользователя, а 110000-119999 - рабочий профиль. Каждое обычное приложение среди них имеет свой уникальный UID.
|
||||
:::
|
||||
|
||||
Каждое приложение может иметь несколько групп, причем GID представляет собой основную группу, которая обычно совпадает с UID. Другие группы называются дополнительными. Определенные разрешения контролируются через группы, например, разрешения на доступ к сети или доступ к Bluetooth.
|
||||
|
||||
Например, если мы выполним команду `id` в оболочке ADB, то результат может выглядеть следующим образом:
|
||||
|
||||
```sh
|
||||
oriole:/ $ id
|
||||
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0
|
||||
```
|
||||
|
||||
Здесь UID равен `2000`, а GID (идентификатор основной группы) также равен `2000`. Кроме того, он входит в несколько дополнительных групп, таких как `inet` (указывает на возможность создания сокетов `AF_INET` и `AF_INET6`) и `sdcard_rw` (указывает на права чтения/записи на SD-карту).
|
||||
|
||||
Корневой профиль KernelSU позволяет настраивать UID, GID и группы для корневого процесса после выполнения команды `su`. Например, в корневом профиле корневого приложения можно установить его UID на `2000`, что означает, что при использовании `su` фактические разрешения приложения будут находиться на уровне оболочки ADB. Группа `inet` может быть удалена, что не позволит команде `su` получить доступ к сети.
|
||||
|
||||
:::tip Примечание
|
||||
Профиль приложений контролирует только разрешения корневого процесса после использования `su`; он не контролирует разрешения самого приложения. Если приложение запросило разрешение на доступ к сети, оно может получить доступ к сети даже без использования `su`. Удаление группы `inet` из `su` только предотвращает доступ `su` к сети.
|
||||
:::
|
||||
|
||||
Корневой профиль реализуется в ядре и не зависит от добровольного поведения root-приложений, в отличие от переключения пользователей или групп через `su`, предоставление прав `su` полностью зависит от пользователя, а не от разработчика.
|
||||
|
||||
### Привилегии
|
||||
|
||||
Привилегии - это механизм разделения привилегий в Linux.
|
||||
|
||||
В традиционных реализациях UNIX для проверки прав доступа выделяются две категории процессов: привилегированные процессы (эффективный идентификатор пользователя равен 0 и называется суперпользователем или root) и непривилегированные процессы (эффективный UID которых не равен нулю). Привилегированные процессы обходят все проверки прав ядра, в то время как непривилегированные процессы подвергаются полной проверке прав на основе учетных данных процесса (обычно: эффективный UID, эффективный GID и список дополнительных групп).
|
||||
|
||||
Начиная с версии Linux 2.2, в Linux привилегии, традиционно ассоциируемые с суперпользователем, разделены на отдельные единицы, называемые возможностями, которые могут быть независимо включены и выключены.
|
||||
|
||||
Каждая способность представляет собой одну или несколько привилегий. Например, `CAP_DAC_READ_SEARCH` представляет собой возможность обхода проверок прав на чтение файлов, а также прав на чтение и выполнение каталогов. Если пользователь с эффективным UID `0` (пользователь root) не имеет возможности `CAP_DAC_READ_SEARCH` или более высоких возможностей, это означает, что, хотя он и является пользователем root, он не может читать файлы по своему усмотрению.
|
||||
|
||||
Корневой профиль KernelSU позволяет настраивать возможности корневого процесса после выполнения `su`, тем самым добиваясь частичного предоставления "прав root". В отличие от вышеупомянутых UID и GID, некоторые root-приложения после использования `su` требуют UID, равный `0`. В таких случаях ограничение возможностей данного root-пользователя с UID `0` может ограничить их разрешенные операции.
|
||||
|
||||
:::tip Настоятельная рекомендация
|
||||
В документе привелегий Linux [официальной документации](https://man7.org/linux/man-pages/man7/capabilities.7.html) дается подробное объяснение возможностей, представленных каждой привелегией. Если вы собираетесь настраивать привелегии, настоятельно рекомендуется сначала прочитать этот документ.
|
||||
:::
|
||||
|
||||
### SELinux
|
||||
|
||||
SELinux - это мощный механизм обязательного контроля доступа (MAC). Он работает по принципу **запрет по умолчанию**: любое действие, не разрешенное в явном виде, запрещается.
|
||||
|
||||
SELinux может работать в двух глобальных режимах:
|
||||
|
||||
1. Разрешительный режим: События запрета регистрируются, но не выполняются.
|
||||
2. Принудительный режим: События запрета регистрируются и выполняются.
|
||||
|
||||
:::warning Предупреждение
|
||||
Современные системы Android в значительной степени опираются на SELinux для обеспечения общей безопасности системы. Настоятельно не рекомендуется использовать пользовательские системы, работающие в "разрешительном режиме", поскольку это не дает существенных преимуществ перед полностью открытой системой.
|
||||
:::
|
||||
|
||||
Объяснение полной концепции SELinux является сложным и выходит за рамки данного документа. Рекомендуется сначала разобраться в его работе с помощью следующих ресурсов:
|
||||
|
||||
1. [Wikipedia](https://en.wikipedia.org/wiki/Security-Enhanced_Linux)
|
||||
2. [Red Hat: Что такое SELinux?](https://www.redhat.com/en/topics/linux/what-is-selinux)
|
||||
3. [ArchLinux: SELinux](https://wiki.archlinux.org/title/SELinux)
|
||||
|
||||
Корневой профиль KernelSU позволяет настраивать SELinux-контекст корневого процесса после выполнения команды `su`. Для этого контекста могут быть заданы специальные правила управления доступом, позволяющие осуществлять тонкий контроль над правами root.
|
||||
|
||||
В типичных сценариях, когда приложение выполняет команду `su`, оно переключает процесс на домен SELinux с **неограниченным доступом**, например `u:r:su:s0`. С помощью профиля Root Profile этот домен может быть переключен на пользовательский домен, например `u:r:app1:s0`, и для него может быть определен ряд правил:
|
||||
|
||||
```sh
|
||||
type app1
|
||||
enforce app1
|
||||
typeattribute app1 mlstrustedsubject
|
||||
allow app1 * * *
|
||||
```
|
||||
|
||||
Обратите внимание, что правило `allow app1 * * *` используется только в демонстрационных целях. На практике это правило не должно широко использоваться, поскольку оно мало чем отличается от разрешительного режима.
|
||||
|
||||
### Эскалация
|
||||
|
||||
При неправильной настройке корневого профиля может возникнуть сценарий эскалации: ограничения, накладываемые корневым профилем, могут непреднамеренно не сработать.
|
||||
|
||||
Например, если предоставить права root пользователю ADB shell (что является обычным случаем), а затем предоставить права root обычному приложению, но настроить его профиль root с UID 2000 (это UID пользователя ADB shell), то приложение может получить полный доступ root, выполнив команду `su` дважды:
|
||||
|
||||
1. При первом выполнении команды `su` будет применен профиль App Profile и произойдет переход на UID `2000` (adb shell) вместо `0` (root).
|
||||
2. При втором выполнении команды `su`, поскольку UID равен `2000`, а в конфигурации вы предоставили доступ root к UID `2000` (adb shell), приложение получит полные привилегии root.
|
||||
|
||||
:::warning Примечание
|
||||
Такое поведение вполне ожидаемо и не является ошибкой. Поэтому мы рекомендуем следующее:
|
||||
|
||||
Если вам действительно необходимо предоставить права root в ADB (например, как разработчику), не рекомендуется изменять UID на `2000` при настройке корневого профиля. Лучше использовать `1000` (система).
|
||||
:::
|
||||
|
||||
## Некорневой профиль
|
||||
|
||||
### Размонтирование модулей
|
||||
|
||||
KernelSU предоставляет бессистемный механизм модификации системных разделов, реализуемый через монтирование overlayfs. Однако некоторые приложения могут быть чувствительны к такому поведению. Поэтому мы можем выгрузить модули, смонтированные в этих приложениях, установив опцию "размонтирование модулей".
|
||||
|
||||
Кроме того, в интерфейсе настроек менеджера KernelSU имеется переключатель "размонтирование модулей по умолчанию". По умолчанию этот переключатель **включен**, что означает, что KernelSU или некоторые модули будут выгружать модули для данного приложения, если не будут применены дополнительные настройки. Если вам не нравится эта настройка или если она влияет на определенные приложения, у вас есть следующие возможности:
|
||||
|
||||
1. Оставить переключатель "размонтирование модулей по умолчанию" и индивидуально отключить опцию "размонтирование модулей" в профиле приложений для приложений, требующих загрузки модулей (действует как "белый список").
|
||||
2. Отключить переключатель "размонтирование модулей по умолчанию" и индивидуально включить опцию "размонтирование модулей" в App Profile для приложений, требующих выгрузки модулей (действует как "черный список").
|
||||
|
||||
:::info
|
||||
В устройствах, использующих ядро версии 5.10 и выше, выгрузку модулей выполняет само ядро. Однако для устройств с ядром версии ниже 5.10 этот переключатель является лишь опцией конфигурации, и KernelSU сам по себе не предпринимает никаких действий. Некоторые модули, например, Zygisksu, могут использовать этот переключатель для определения необходимости выгрузки модулей.
|
||||
:::
|
||||
@@ -1,26 +0,0 @@
|
||||
# Различия с Magisk {#title}
|
||||
|
||||
Несмотря на большое количество сходств между модулями KernelSU и модулями Magisk, неизбежно возникают и различия, обусловленные совершенно разными механизмами их реализации. Если вы хотите, чтобы ваш модуль работал как на Magisk, так и на KernelSU, вы должны понимать эти различия.
|
||||
|
||||
## Сходства {#similarities}
|
||||
|
||||
- Формат файлов модулей: оба используют формат zip для организации модулей, и формат модулей практически одинаков
|
||||
- Каталог установки модулей: оба расположены в `/data/adb/modules`.
|
||||
- Бессистемность: оба поддерживают модификацию /system бессистемным способом через модули
|
||||
- post-fs-data.sh: время выполнения и семантика полностью совпадают
|
||||
- service.sh: время выполнения и семантика полностью совпадают
|
||||
- system.prop: полностью совпадает
|
||||
- sepolicy.rule: полностью совпадает
|
||||
- BusyBox: скрипты запускаются в BusyBox с включенным "автономным режимом" в обоих случаях
|
||||
|
||||
## Различия {#differences}
|
||||
|
||||
Прежде чем разбираться в различиях, необходимо знать, как отличить, в каком режиме работает ваш модуль - KernelSU или Magisk. Для этого можно использовать переменную окружения `KSU` во всех местах, где можно запустить скрипты модуля (`customize.sh`, `post-fs-data.sh`, `service.sh`). В KernelSU эта переменная окружения будет установлена в значение `true`.
|
||||
|
||||
Вот некоторые отличия:
|
||||
|
||||
- Модули KernelSU не могут быть установлены в режиме Recovery.
|
||||
- Модули KernelSU не имеют встроенной поддержки Zygisk (но вы можете использовать модули Zygisk через [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
- Метод замены или удаления файлов в модулях KernelSU полностью отличается от Magisk. KernelSU не поддерживает метод `.replace`. Вместо этого необходимо создать одноименный файл с помощью команды `mknod filename c 0 0` для удаления соответствующего файла.
|
||||
- Каталоги для BusyBox отличаются. Встроенный BusyBox в KernelSU находится в каталоге `/data/adb/ksu/bin/busybox`, а в Magisk - в каталоге `/data/adb/magisk/busybox`. **Обратите внимание, что это внутреннее поведение KernelSU и в будущем оно может измениться!**
|
||||
- KernelSU не поддерживает файлы `.replace`; однако KernelSU поддерживает переменные `REMOVE` и `REPLACE` для удаления или замены файлов и папок.
|
||||
@@ -1,67 +0,0 @@
|
||||
# FAQ
|
||||
|
||||
## Поддерживает ли KernelSU мое устройство?
|
||||
|
||||
Во-первых, ваше устройство должно быть способно разблокировать загрузчик. Если не может, значит, устройство не поддерживается.
|
||||
|
||||
Затем установите на устройство приложение KernelSU manager App и откройте его, если оно покажет `Unsupported`, то ваше устройство не поддерживается из коробки, но вы можете собрать исходный код ядра и интегрировать KernelSU, чтобы заставить его работать, или использовать [неофициально-поддерживаемые-устройства](unofficially-support-devices).
|
||||
|
||||
## Нужно ли для KernelSU разблокировать загрузчик?
|
||||
|
||||
Безусловно, да.
|
||||
|
||||
## Поддерживает ли KernelSU модули?
|
||||
|
||||
Да, но это ранняя версия, она может быть глючной. Пожалуйста, подождите, пока она станет стабильной :)
|
||||
|
||||
## Поддерживает ли KernelSU Xposed?
|
||||
|
||||
Да, [Dreamland](https://github.com/canyie/Dreamland) и [TaiChi](https://taichi.cool) работают. Что касается LSPosed, то его можно заставить работать с помощью [Zygisk на KernelSU](https://github.com/Dr-TSNG/ZygiskNext)
|
||||
|
||||
## Поддерживает ли KernelSU Zygisk?
|
||||
|
||||
KernelSU не имеет встроенной поддержки Zygisk, но вы можете использовать [Zygisk на KernelSU](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## Совместим ли KernelSU с Magisk?
|
||||
|
||||
Система модулей KernelSU конфликтует с магическим монтированием Magisk, если в KernelSU включен какой-либо модуль, то весь Magisk не будет работать.
|
||||
|
||||
Но если вы используете только `su` из KernelSU, то он будет хорошо работать с Magisk: KernelSU модифицирует `kernel`, а Magisk - `ramdisk`, они могут работать вместе.
|
||||
|
||||
## Заменит ли KernelSU Magisk?
|
||||
|
||||
Мы так не считаем, и это не является нашей целью. Magisk достаточно хорош для решения проблемы root в пользовательском пространстве и будет жить долго. Цель KernelSU - предоставить пользователям интерфейс ядра, а не заменить Magisk.
|
||||
|
||||
## Может ли KernelSU поддерживать устройства, не относящиеся к GKI?
|
||||
|
||||
Это возможно. Но для этого необходимо скачать исходный текст ядра, подключить KernelSU к дереву исходных текстов и скомпилировать ядро самостоятельно.
|
||||
|
||||
## Может ли KernelSU поддерживать устройства под управлением Android 12?
|
||||
|
||||
На совместимость KernelSU влияет ядро устройства, и версия Android здесь ни при чем. Единственное ограничение - устройства, запускаемые с Android 12, должны иметь ядро 5.10+ (устройства GKI). Итак:
|
||||
|
||||
1. Устройства, выпущенные под управлением Android 12, должны поддерживаться.
|
||||
2. Устройства со старым ядром (некоторые устройства с Android 12 также имеют старое ядро) совместимы (Вы должны собрать ядро самостоятельно).
|
||||
|
||||
## Может ли KernelSU поддерживать старое ядро?
|
||||
|
||||
Это возможно, KernelSU бэкпортирован на ядро 4.14, для более старых ядер, вам нужно сделать бэкпорт вручную, и PR приветствуются!
|
||||
|
||||
## Как интегрировать KernelSU в старое ядро?
|
||||
|
||||
Пожалуйста, обратитесь к [руководству](how-to-integrate-for-non-gki)
|
||||
|
||||
## Почему моя версия Android - 13, а ядро показывает "android12-5.10"?
|
||||
|
||||
Версия ядра не имеет никакого отношения к версии Android, если вам нужно прошить ядро, всегда используйте версию ядра, версия Android не так важна.
|
||||
|
||||
## Есть ли в KernelSU пространство имен --mount-master/global mount?
|
||||
|
||||
Сейчас нет (возможно, в будущем), но есть много способов переключиться на глобальное пространство имен монтирования вручную, например:
|
||||
|
||||
1. `nsenter -t 1 -m sh` для получения оболочки в глобальном пространстве имен монтирования.
|
||||
2. Добавить `nsenter --mount=/proc/1/ns/mnt` к команде, которую вы хотите выполнить, тогда команда будет выполнена в глобальном пространстве имен монтирования. KernelSU также [использует этот способ](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/shirkneko/zako/mksu/ui/util/KsuCli.kt#L115)
|
||||
|
||||
## Я GKI1.0, могу ли я использовать это?
|
||||
|
||||
GKI1 полностью отличается от GKI2, вы должны скомпилировать ядро самостоятельно.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Скрытые возможности
|
||||
|
||||
## .ksurc
|
||||
|
||||
По умолчанию `/system/bin/sh` загружает `/system/etc/mkshrc`.
|
||||
|
||||
Вы можете заставить su загружать пользовательский rc-файл, создав файл `/data/adb/ksu/.ksurc`.
|
||||
@@ -1,65 +0,0 @@
|
||||
# Как собрать KernelSU?
|
||||
|
||||
Прежде всего, необходимо ознакомиться с официальной документацией Android по сборке ядра:
|
||||
|
||||
1. [Сборка ядер](https://source.android.com/docs/setup/build/building-kernels)
|
||||
2. [Сборки релизов GKI](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
::: warning
|
||||
Эта страница предназначена для устройств GKI, если вы используете старое ядро, пожалуйста, обратитесь к [Как интегрировать KernelSU для не GKI ядер?](how-to-integrate-for-non-gki).
|
||||
:::
|
||||
|
||||
## Сборка ядра
|
||||
|
||||
### Синхронизация исходного кода ядра
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
Файл `<kernel_manifest.xml>` - это файл манифеста, который может однозначно определять сборку, с его помощью можно выполнить пересборку. Файл манифеста следует загрузить с сайта [Сборки релизов Google GKI](https://source.android.com/docs/core/architecture/kernel/gki-release-builds)
|
||||
|
||||
### Построение
|
||||
|
||||
Пожалуйста, сначала ознакомьтесь с [официальной документацией](https://source.android.com/docs/setup/build/building-kernels).
|
||||
|
||||
Например, нам необходимо собрать образ ядра aarch64:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Не забудьте добавить флаг `LTO=thin`, иначе сборка может завершиться неудачей, если память вашего компьютера меньше 24 Гб.
|
||||
|
||||
Начиная с Android 13, сборка ядра осуществляется с помощью `bazel`:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
|
||||
## Сборка ядра с помощью KernelSU
|
||||
|
||||
Если вы успешно собрали ядро, то собрать KernelSU очень просто, выберите любой запуск в корневом каталоге исходного кода ядра:
|
||||
|
||||
- Последний тэг(стабильный)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
- Основная ветвь(разработка)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
- Выбранный тэг(Например, версия v0.5.2)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
А затем пересоберите ядро и получите образ ядра с KernelSU!
|
||||
@@ -1,264 +0,0 @@
|
||||
# Как интегрировать KernelSU для не GKI ядер? {#introduction}
|
||||
|
||||
KernelSU может быть интегрирован в ядра, отличные от GKI, и был перенесен на версии 4.14 и ниже.
|
||||
|
||||
В связи с фрагментацией ядер, отличных от GKI, у нас нет единого способа их сборки, поэтому мы не можем предоставить загрузочные образы, отличные от GKI. Однако вы можете собрать ядро самостоятельно с помощью интегрированной программы KernelSU.
|
||||
|
||||
Во-первых, вы должны уметь собирать загрузочное ядро из исходных текстов ядра. Если ядро не является открытым, то запустить KernelSU для вашего устройства будет затруднительно.
|
||||
|
||||
Если вы можете собрать загрузочное ядро, то существует два способа интеграции KernelSU в исходный код ядра:
|
||||
|
||||
1. Автоматически с помощью `kprobe`
|
||||
2. Вручную
|
||||
|
||||
## Интеграция с kprobe {#using-kprobes}
|
||||
|
||||
KernelSU использует kprobe для выполнения хуков ядра, если *kprobe* хорошо работает в вашем ядре, то рекомендуется использовать именно этот способ.
|
||||
|
||||
Сначала добавьте KernelSU в дерево исходных текстов ядра:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
Затем необходимо проверить, включена ли функция *kprobe* в конфигурации ядра, если нет, то добавьте в нее эти настройки:
|
||||
|
||||
```
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
И снова соберите ядро, KernelSU должен работать нормально.
|
||||
|
||||
Если вы обнаружите, что KPROBES по-прежнему не активирован, попробуйте включить `CONFIG_MODULES`. (Если это все равно не даст результата, используйте `make menuconfig` для поиска других зависимостей KPROBES).
|
||||
|
||||
Если же при интеграции KernelSU возникает зацикливание загрузки, то, возможно, в вашем ядре *kprobe неисправен*, следует исправить ошибку kprobe или воспользоваться вторым способом.
|
||||
|
||||
:::tip Как проверить, не сломан ли kprobe?
|
||||
|
||||
закомментируйте `ksu_enable_sucompat()` и `ksu_enable_ksud()` в файле `KernelSU/kernel/ksu.c`, если устройство загружается нормально, то может быть нарушена работа kprobe.
|
||||
:::
|
||||
|
||||
## Ручная модификация исходного кода ядра {#modify-kernel-source-code}
|
||||
|
||||
Если kprobe не работает в вашем ядре (возможно, это ошибка апстрима или ядра ниже 4.8), то можно попробовать следующий способ:
|
||||
|
||||
Сначала добавьте Kernel SU в дерево исходного кода вашего ядра:
|
||||
|
||||
- Последний тэг(стабильный)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
- Основная ветвь(разработка)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
- Выбранный тэг(Например, версия v0.5.2)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
Затем добавьте вызовы KernelSU в исходный код ядра, вот патч, на который можно сослаться:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Get basic and extra attributes by filename
|
||||
* @dfd: A file descriptor representing the base dir for a relative filename
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
В исходных кодах ядра можно найти эти четыре функции:
|
||||
|
||||
1. do_faccessat, обычно в `fs/open.c`.
|
||||
2. do_execveat_common, обычно в `fs/exec.c`.
|
||||
3. vfs_read, обычно в `fs/read_write.c`.
|
||||
4. vfs_statx, обычно в `fs/stat.c`.
|
||||
|
||||
Если в вашем ядре нет `vfs_statx`, используйте вместо него `vfs_fstatat`:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fstat);
|
||||
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+
|
||||
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int flag)
|
||||
{
|
||||
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = 0;
|
||||
|
||||
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||
+
|
||||
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH)) != 0)
|
||||
goto out;
|
||||
```
|
||||
|
||||
Для ядер младше 4.17, если вы не можете найти `do_faccessat`, просто перейдите к определению системного вызова `faccessat` и поместите вызов туда:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 2ff887661237..e758d7db7663 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -355,6 +355,9 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return error;
|
||||
}
|
||||
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
+
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -370,6 +373,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
+
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
Чтобы включить встроенный в KernelSU безопасный режим, необходимо также изменить `input_handle_event` в файле `drivers/input/input.c`:
|
||||
|
||||
:::tip
|
||||
Настоятельно рекомендуется включить эту функцию, она очень помогает предотвратить циклическую загрузку!
|
||||
:::
|
||||
|
||||
```diff
|
||||
diff --git a/drivers/input/input.c b/drivers/input/input.c
|
||||
index 45306f9ef247..815091ebfca4 100755
|
||||
--- a/drivers/input/input.c
|
||||
+++ b/drivers/input/input.c
|
||||
@@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev,
|
||||
return disposition;
|
||||
}
|
||||
|
||||
+extern bool ksu_input_hook __read_mostly;
|
||||
+extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value);
|
||||
+
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition = input_get_disposition(dev, type, code, &value);
|
||||
+
|
||||
+ if (unlikely(ksu_input_hook))
|
||||
+ ksu_handle_input_handle_event(&type, &code, &value);
|
||||
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
```
|
||||
|
||||
Наконец, снова соберите ядро, KernelSU должен работать хорошо.
|
||||
@@ -1,169 +0,0 @@
|
||||
# Установка {#title}
|
||||
|
||||
## Проверьте, поддерживается ли ваше устройство {#check-if-supported}
|
||||
|
||||
Скачайте приложение менеджера KernelSU с сайта [GitHub Releases](https://github.com/tiann/KernelSU/releases) и установите его на устройство:
|
||||
|
||||
- Если приложение показывает `Unsupported`, это означает, что **Вы должны скомпилировать ядро самостоятельно**, KernelSU не будет и никогда не предоставит Вам загрузочный образ для прошивки.
|
||||
- Если приложение показывает `Не установлено`, значит, ваши устройства официально поддерживаются KernelSU.
|
||||
|
||||
:::info
|
||||
Для устройств, показывающих `Unsupported`, здесь находится [Unofficially-support-devices](unofficially-support-devices.md), вы можете скомпилировать ядро самостоятельно.
|
||||
:::
|
||||
|
||||
## Резервное копирование стокового файла boot.img {#backup-boot-image}
|
||||
|
||||
Перед прошивкой необходимо создать резервную копию файла boot.img. Если возникнет ошибка загрузки, вы всегда сможете восстановить систему, перепрошив ее на заводскую загрузку с помощью fastboot.
|
||||
|
||||
::: warning
|
||||
Прошивка может привести к потере данных, поэтому обязательно выполните этот шаг перед переходом к следующему шагу!!! При необходимости можно также создать резервную копию всех данных на телефоне.
|
||||
:::
|
||||
|
||||
## Необходимые знания {#acknowage}
|
||||
|
||||
### ADB и fastboot {#adb-and-fastboot}
|
||||
|
||||
По умолчанию в этом руководстве вы будете использовать инструменты ADB и fastboot, поэтому, если вы их не знаете, рекомендуем сначала воспользоваться поисковой системой, чтобы узнать о них.
|
||||
|
||||
### KMI
|
||||
|
||||
Kernel Module Interface (KMI), версии ядра с одинаковым KMI **совместимы** Это то, что в GKI означает "общий"; наоборот, если KMI отличается, то эти ядра несовместимы друг с другом, и прошивка образа ядра с другим KMI, чем у вашего устройства, может привести к bootloop.
|
||||
|
||||
В частности, для устройств GKI формат версии ядра должен быть следующим:
|
||||
|
||||
```txt
|
||||
KernelRelease :=
|
||||
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
|
||||
w .x .y -zzz -k -something
|
||||
```
|
||||
|
||||
`w.x-zz-k` - версия KMI. Например, если версия ядра устройства `5.10.101-android12-9-g30979850fc20`, то его KMI - `5.10-android12-9`; теоретически оно может нормально загружаться с другими ядрами KMI.
|
||||
|
||||
::: tip
|
||||
Обратите внимание, что SubLevel в версии ядра не является частью KMI! Это означает, что `5.10.101-android12-9-g30979850fc20` имеет тот же KMI, что и `5.10.137-android12-9-g30979850fc20`!
|
||||
:::
|
||||
|
||||
### Версия ядра и версия Android {#kernel-version-vs-android-version}
|
||||
|
||||
Обратите внимание: **Версия ядра и версия Android - это не обязательно одно и то же!**
|
||||
|
||||
Если вы обнаружили, что версия ядра `android12-5.10.101`, а версия системы Android - Android 13 или другая, не удивляйтесь, поскольку номер версии системы Android не обязательно совпадает с номером версии ядра Linux; Номер версии ядра Linux обычно соответствует версии системы Android, поставляемой с **устройством при его поставке**. При последующем обновлении системы Android версия ядра, как правило, не меняется. При необходимости прошивки **укажите версию ядра!!!**.
|
||||
|
||||
## Введение {#installation-introduction}
|
||||
|
||||
Существует несколько способов установки KernelSU, каждый из которых подходит для разных сценариев, поэтому выбирайте их по своему усмотрению.
|
||||
|
||||
1. Установка с помощью пользовательского Recovery (например, TWRP)
|
||||
2. Установка с помощью приложения для прошивки ядра, например, Franco Kernel Manager
|
||||
3. Установка с помощью fastboot с использованием boot.img, предоставленного KernelSU
|
||||
4. Восстановить boot.img вручную и установить его
|
||||
|
||||
## Установка с помощью пользовательского Recovery {#install-by-recovery}
|
||||
|
||||
Необходимые условия: На устройстве должен быть установлен пользовательский Recovery, например TWRP; если его нет или доступен только официальный Recovery, воспользуйтесь другим способом.
|
||||
|
||||
Шаг:
|
||||
|
||||
1. С [Release page](https://github.com/tiann/KernelSU/releases) KernelSU загрузите zip-пакет, начинающийся с AnyKernel3, который соответствует версии вашего телефона; например, версия ядра телефона - `android12-5.10. 66`, то следует скачать файл `AnyKernel3-android12-5.10.66_yyy-MM.zip` (где `yyyy` - год, а `MM` - месяц).
|
||||
2. Перезагрузите телефон в TWRP.
|
||||
3. С помощью adb поместите AnyKernel3-*.zip в /sdcard телефона и выберите установку в графическом интерфейсе TWRP; или вы можете напрямую `adb sideload AnyKernel-*.zip` для установки.
|
||||
|
||||
PS. Данный способ подходит для любой установки (не ограничиваясь начальной установкой или последующими обновлениями), если вы используете TWRP.
|
||||
|
||||
## Установка с помощью Kernel Flasher {#install-by-kernel-flasher}
|
||||
|
||||
Необходимые условия: Ваше устройство должно быть рутованным. Например, вы установили Magisk, чтобы получить root, или установили старую версию KernelSU и должны обновить ее до другой версии; если ваше устройство не укоренено, попробуйте другие методы.
|
||||
|
||||
Шаг:
|
||||
|
||||
1. Загрузите zip-архив AnyKernel3; инструкции по загрузке см. в разделе *Установка с помощью пользовательского Recovery*.
|
||||
2. Откройте приложение для прошивки ядра и используйте предоставленный AnyKernel3 zip для прошивки.
|
||||
|
||||
Если вы раньше не использовали приложение для прошивки ядра, то наиболее популярными являются следующие.
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
PS. Этот способ более удобен при обновлении KernelSU и может быть выполнен без компьютера (сначала сделайте резервную копию!). .
|
||||
|
||||
## Установка с помощью boot.img, предоставленного KernelSU {#install-by-kernelsu-boot-image}
|
||||
|
||||
Этот способ не требует наличия TWRP и root-прав на телефоне; он подходит для первой установки KernelSU.
|
||||
|
||||
### Найти подходящий boot.img {#found-propery-image}
|
||||
|
||||
KernelSU предоставляет общий boot.img для устройств GKI, и его необходимо прошить в загрузочный раздел устройства.
|
||||
|
||||
Вы можете загрузить boot.img с [GitHub Release](https://github.com/tiann/KernelSU/releases), обратите внимание, что вы должны использовать правильную версию boot.img. Например, если на устройстве установлено ядро `android12-5.10.101`, то необходимо загрузить `android-5.10.101_yyy-MM.boot-<format>.img`. , необходимо загрузить `android-5.10.101_yyy-MM.boot-<format>.img`.(Соблюдайте соответствие KMI!).
|
||||
|
||||
Где `<format>` означает формат сжатия ядра в официальном boot.img, проверьте формат сжатия ядра в оригинальном boot.img, вы должны использовать правильный формат, например, `lz4`, `gz`; если вы используете неправильный формат сжатия, вы можете столкнуться с bootloop.
|
||||
|
||||
::: info
|
||||
1. Вы можете использовать magiskboot для получения формата сжатия исходной загрузки; конечно, вы также можете спросить других, более опытных ребят с той же моделью, что и ваше устройство. Кроме того, формат сжатия ядра обычно не меняется, поэтому, если вы успешно загрузились с определенным форматом сжатия, вы можете попробовать этот формат позже.
|
||||
2. Устройства Xiaomi обычно используют `gz` или **без сжатия**.
|
||||
3. Для устройств Pixel следуйте приведенным ниже инструкциям.
|
||||
:::
|
||||
|
||||
### прошить boot.img на устройство {#flash-boot-image}
|
||||
|
||||
Используйте `adb` для подключения устройства, затем выполните `adb reboot bootloader` для входа в режим fastboot, после чего используйте эту команду для прошивки KernelSU:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
::: info
|
||||
Если устройство поддерживает `fastboot boot`, можно сначала использовать `fastboot boot boot.img`, чтобы попытаться использовать boot.img для загрузки системы. Если произойдет что-то непредвиденное, перезагрузите его снова для загрузки.
|
||||
:::
|
||||
|
||||
### перезагрузка {#reboot}
|
||||
|
||||
После завершения прошивки необходимо перезагрузить устройство:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
## Исправить boot.img вручную {#patch-boot-image}
|
||||
|
||||
Для некоторых устройств формат boot.img не так распространен, например, не `lz4`, `gz` или несжатый; наиболее типичным является Pixel, его boot.img имеет формат `lz4_legacy` со сжатием, ramdisk может быть `gz`, также может быть `lz4_legacy` со сжатием; в это время, если напрямую прошить boot.img, предоставляемый KernelSU, телефон может не загрузиться; в это время можно вручную исправить boot.img для достижения цели.
|
||||
|
||||
Как правило, существует два способа исправления:
|
||||
|
||||
1. [Android-Image-Kitchen](https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/)
|
||||
2. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
|
||||
Среди них Android-Image-Kitchen подходит для работы на ПК, а magiskboot нуждается в сотрудничестве мобильного телефона.
|
||||
|
||||
### Подготовка {#patch-preparation}
|
||||
|
||||
1. Получите стоковый boot.img вашего телефона; его можно получить у производителя устройства, возможно, вам понадобится [payload-dumper-go](https://github.com/ssut/payload-dumper-go)
|
||||
2. Загрузите zip-файл AnyKernel3, предоставленный KernelSU, который соответствует версии KMI вашего устройства (можно обратиться к разделу *Установка с помощью пользовательского Recovery*).
|
||||
3. Распакуйте пакет AnyKernel3 и получите файл `Image`, который является файлом ядра KernelSU.
|
||||
|
||||
### Использование Android-Image-Kitchen {#using-android-image-kitchen}
|
||||
|
||||
1. Загрузите программу Android-Image-Kitchen на свой компьютер.
|
||||
2. Поместите файл boot.img в корневую папку Android-Image-Kitchen.
|
||||
3. Выполните команду `./unpackimg.sh boot.img` в корневом каталоге Android-Image-Kitchen, в результате чего boot.img распакуется и появятся некоторые файлы.
|
||||
4. Замените `boot.img-kernel` в каталоге `split_img` тем `образом`, который вы извлекли из AnyKernel3 (обратите внимание на изменение названия на boot.img-kernel).
|
||||
5. Выполните команду `./repackimg.sh` в корневом каталоге 在 Android-Image-Kitchen; Вы получите файл с именем `image-new.img`; Прошейте этот boot.img с помощью fastboot (см. предыдущий раздел).
|
||||
|
||||
### Использование magiskboot {#using magiskboot}
|
||||
|
||||
1. Загрузите последнюю версию Magisk с [Release Page](https://github.com/topjohnwu/Magisk/releases).
|
||||
2. Переименуйте `Magisk-*(version).apk` в `Magisk-*.zip` и разархивируйте его.
|
||||
3. Закачайте `Magisk-*/lib/arm64-v8a/libmagiskboot.so` на устройство с помощью adb: `adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot`.
|
||||
4. Установите на устройство стоковый boot.img и образ в AnyKernel3.
|
||||
5. Войдите в оболочку adb и перейдите в каталог `/data/local/tmp/`, затем `chmod +x magiskboot`.
|
||||
6. Войдите в adb shell и cd директории `/data/local/tmp/`, выполните команду `./magiskboot unpack boot.img` для распаковки `boot.img`, вы получите файл `kernel`, это и есть ваше стоковое ядро.
|
||||
7. Замените `kernel` на `Image`: `mv -f Image kernel`.
|
||||
8. Выполните команду `./magiskboot repack boot.img`, чтобы перепаковать boot img, и получите файл `new-boot.img`, прошейте его на устройство с помощью fastboot.
|
||||
|
||||
## Другие методы {#other-methods}
|
||||
|
||||
На самом деле все эти способы установки имеют только одну основную идею - **заменить исходное ядро на ядро, предоставляемое KernelSU**; если это возможно, то установка возможна; например, возможны следующие способы.
|
||||
|
||||
1. Сначала установить Magisk, получить права root через Magisk, а затем с помощью kernel flasher прошить AnyKernel zip из KernelSU.
|
||||
2. Использовать какой-либо инструментарий для прошивки на ПК, чтобы прошить ядро, предоставленное KernelSU.
|
||||
@@ -1,255 +0,0 @@
|
||||
# Руководство по разработке модулей {#introduction}
|
||||
|
||||
KernelSU предоставляет механизм модулей, позволяющий добиться эффекта модификации системного каталога при сохранении целостности системного раздела. Этот механизм принято называть "бессистемным".
|
||||
|
||||
Модульный механизм KernelSU практически аналогичен механизму Magisk. Если вы знакомы с разработкой модулей Magisk, то разработка модулей KernelSU очень похожа. Представление модулей ниже можно пропустить, достаточно прочитать [различия-с-magisk] (difference-with-magisk.md).
|
||||
|
||||
## Busybox
|
||||
|
||||
В комплект поставки KernelSU входит полнофункциональный бинарный файл BusyBox (включая полную поддержку SELinux). Исполняемый файл находится по адресу `/data/adb/ksu/bin/busybox`. BusyBox от KernelSU поддерживает переключаемый во время работы "ASH Standalone Shell Mode". Этот автономный режим означает, что при запуске в оболочке `ash` BusyBox каждая команда будет напрямую использовать апплет внутри BusyBox, независимо от того, что задано в качестве `PATH`. Например, такие команды, как `ls`, `rm`, `chmod` будут **НЕ** использовать то, что находится в `PATH` (в случае Android по умолчанию это будут `/system/bin/ls`, `/system/bin/rm` и `/system/bin/chmod` соответственно), а вместо этого будут напрямую вызывать внутренние апплеты BusyBox. Это гарантирует, что скрипты всегда будут выполняться в предсказуемом окружении и всегда будут иметь полный набор команд, независимо от того, на какой версии Android они выполняются. Чтобы заставить команду _не_ использовать BusyBox, необходимо вызвать исполняемый файл с полными путями.
|
||||
|
||||
Каждый сценарий оболочки, запущенный в контексте KernelSU, будет выполняться в оболочке BusyBox `ash` с включенным автономным режимом. Для сторонних разработчиков это касается всех загрузочных скриптов и скриптов установки модулей.
|
||||
|
||||
Для тех, кто хочет использовать эту возможность "Автономного режима" вне KernelSU, есть два способа включить ее:
|
||||
|
||||
1. Установите переменной окружения `ASH_STANDALONE` значение `1`<br>Пример: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Переключитесь с помощью параметров командной строки:<br>`/data/adb/ksu/bin/busybox sh -o standalone <script>`
|
||||
|
||||
Чтобы убедиться, что все последующие запуски оболочки `sh` также выполняются в автономном режиме, предпочтительным методом является вариант 1 (и это то, что KernelSU и менеджер KernelSU используют внутри), поскольку переменные окружения наследуются вплоть до дочерних процессов.
|
||||
|
||||
::: tip отличие от Magisk
|
||||
|
||||
BusyBox в KernelSU теперь использует бинарный файл, скомпилированный непосредственно из проекта Magisk. **Поэтому вам не нужно беспокоиться о проблемах совместимости между скриптами BusyBox в Magisk и KernelSU, поскольку они абсолютно одинаковы!
|
||||
:::
|
||||
|
||||
## Модули KernelSU {#kernelsu-modules}
|
||||
|
||||
Модуль KernelSU - это папка, размещенная в каталоге `/data/adb/modules` и имеющая следующую структуру:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- Папка имеет имя с идентификатором модуля
|
||||
│ │
|
||||
│ │ *** Идентификация модуля ***
|
||||
│ │
|
||||
│ ├── module.prop <--- В этом файле хранятся метаданные модуля
|
||||
│ │
|
||||
│ │ *** Основное содержимое ***
|
||||
│ │
|
||||
│ ├── system <--- Эта папка будет смонтирована, если skip_mount не существует
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** Флаги состояния ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- Если он существует, то KernelSU НЕ будет монтировать вашу системную папку
|
||||
│ ├── disable <--- Если модуль существует, то он будет отключен
|
||||
│ ├── remove <--- Если модуль существует, то при следующей перезагрузке он будет удален
|
||||
│ │
|
||||
│ │ *** Необязательные файлы ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- Этот скрипт будет выполняться в post-fs-data
|
||||
│ ├── service.sh <--- Этот скрипт будет выполняться в сервисе late_start
|
||||
| ├── uninstall.sh <--- Этот скрипт будет выполнен, когда KernelSU удалит ваш модуль
|
||||
│ ├── system.prop <--- Свойства из этого файла будут загружены в качестве системных свойств программой resetprop
|
||||
│ ├── sepolicy.rule <--- Дополнительные пользовательские правила sepolicy
|
||||
│ │
|
||||
│ │ *** Автоматически генерируется, НЕЛЬЗЯ создавать или изменять вручную ***
|
||||
│ │
|
||||
│ ├── vendor <--- Символьная ссылка на $MODID/system/vendor
|
||||
│ ├── product <--- Символьная ссылка на $MODID/system/product
|
||||
│ ├── system_ext <--- Симлинк на $MODID/system/system_ext
|
||||
│ │
|
||||
│ │ *** Допускается использование любых дополнительных файлов/папок ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: tip различия с Magisk
|
||||
KernelSU не имеет встроенной поддержки Zygisk, поэтому в модуле нет содержимого, связанного с Zygisk. Однако для поддержки модулей Zygisk можно использовать [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext). В этом случае содержимое модуля Zygisk идентично содержимому, поддерживаемому Magisk.
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
module.prop - это конфигурационный файл модуля. В KernelSU, если модуль не содержит этого файла, он не будет распознан как модуль. Формат этого файла следующий:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versionCode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` должно соответствовать данному регулярному выражению: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
экс: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
Это **уникальный идентификатор** вашего модуля. Не следует изменять его после публикации.
|
||||
- `versionCode` должен быть **целым**. Это используется для сравнения версий
|
||||
- Другими, не упомянутыми выше, могут быть любые **однострочные** строки.
|
||||
- Обязательно используйте тип перевода строки `UNIX (LF)`, а не `Windows (CR+LF)` или `Macintosh (CR)`.
|
||||
|
||||
### Сценарии командной оболочки {#shell-scripts}
|
||||
|
||||
Чтобы понять разницу между `post-fs-data.sh` и `Service.sh`, прочитайте раздел [Boot Scripts](#boot-scripts). Для большинства разработчиков модулей `service.sh` должно быть достаточно, если вам нужно просто запустить загрузочный скрипт.
|
||||
|
||||
Во всех скриптах вашего модуля используйте `MODDIR=${0%/*}` для получения пути к базовому каталогу вашего модуля; **НЕ** кодируйте жестко путь к вашему модулю в скриптах.
|
||||
|
||||
::: tip различия с Magisk
|
||||
С помощью переменной окружения KSU можно определить, выполняется ли сценарий в KernelSU или в Magisk. Если скрипт выполняется в KernelSU, то это значение будет равно true.
|
||||
:::
|
||||
|
||||
### каталог `system` {#system-directories}
|
||||
|
||||
После загрузки системы содержимое этого каталога будет наложено поверх раздела /system с помощью overlayfs. Это означает, что:
|
||||
|
||||
1. Файлы с теми же именами, что и в соответствующем каталоге в системе, будут перезаписаны файлами в этом каталоге.
|
||||
2. Папки с теми же именами, что и в соответствующем каталоге в системе, будут объединены с папками в этом каталоге.
|
||||
|
||||
Если вы хотите удалить файл или папку в исходном каталоге системы, необходимо создать файл с тем же именем, что и файл/папка, в каталоге модуля с помощью команды `mknod filename c 0 0`. Таким образом, система overlayfs автоматически "забелит" этот файл, как если бы он был удален (раздел /system при этом фактически не изменится).
|
||||
|
||||
Вы также можете объявить в `customize.sh` переменную с именем `REMOVE`, содержащую список каталогов для выполнения операций удаления, и KernelSU автоматически выполнит команду `mknod <TARGET> c 0 0` в соответствующих каталогах модуля. Например:
|
||||
|
||||
```sh
|
||||
REMOVE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
В приведенном выше списке будут выполнены команды `mknod $MODPATH/system/app/YouTuBe c 0 0` и `mknod $MODPATH/system/app/Bloatware c 0 0`; при этом `/system/app/YouTube` и `/system/app/Bloatware` будут удалены после вступления модуля в силу.
|
||||
|
||||
Если вы хотите заменить каталог в системе, то необходимо создать каталог с тем же путем в каталоге модуля, а затем установить для этого каталога атрибут `setfattr -n trusted.overlay.opaque -v y <TARGET>`. Таким образом, система overlayfs автоматически заменит соответствующий каталог в системе (без изменения раздела /system).
|
||||
|
||||
Вы можете объявить в файле `customize.sh` переменную с именем `REPLACE`, содержащую список заменяемых каталогов, и KernelSU автоматически выполнит соответствующие операции в каталоге вашего модуля. Например:
|
||||
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
|
||||
В этом списке будут автоматически созданы каталоги `$MODPATH/system/app/YouTube` и `$MODPATH/system/app/Bloatware`, а затем выполнены команды `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube` и `setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware`. После вступления модуля в силу каталоги `/system/app/YouTube` и `/system/app/Bloatware` будут заменены на пустые.
|
||||
|
||||
::: tip различия с Magisk
|
||||
|
||||
В KernelSU бессистемный механизм реализован через overlayfs ядра, а в Magisk в настоящее время используется магическое монтирование (bind mount). Эти два метода реализации имеют существенные различия, но конечная цель у них одна: модификация файлов /system без физического изменения раздела /system.
|
||||
:::
|
||||
|
||||
Если вы заинтересованы в использовании overlayfs, рекомендуется прочитать [документацию по overlayfs](https://docs.kernel.org/filesystems/overlayfs.html) ядра Linux.
|
||||
|
||||
### system.prop
|
||||
|
||||
Этот файл имеет тот же формат, что и `build.prop`. Каждая строка состоит из `[key]=[value]`.
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
Если для вашего модуля требуются дополнительные патчи sepolicy, добавьте эти правила в данный файл. Каждая строка в этом файле будет рассматриваться как утверждение политики.
|
||||
|
||||
## Установщик модулей {#module-installer}
|
||||
|
||||
Инсталлятор модуля KernelSU - это модуль KernelSU, упакованный в zip-файл, который может быть прошит в APP-менеджере KernelSU. Простейший установщик модуля KernelSU - это просто модуль KernelSU, упакованный в zip-файл.
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (Необязательно, более подробно позже)
|
||||
│ Этот скрипт будет использоваться в update-binary
|
||||
├── ...
|
||||
├── ... /* Остальные файлы модуля */
|
||||
│
|
||||
```
|
||||
|
||||
:::warning
|
||||
Модуль KernelSU НЕ поддерживается для установки в пользовательское Recovery!!!
|
||||
:::
|
||||
|
||||
### Персонализация {#customizing-installation}
|
||||
|
||||
Если вам необходимо настроить процесс установки модуля, то в качестве опции вы можете создать в программе установки скрипт с именем `customize.sh`. Этот скрипт будет _источником_ (не исполняться!) сценария установщика модуля после извлечения всех файлов и применения стандартных разрешений и secontext. Это очень удобно, если ваш модуль требует дополнительной настройки в зависимости от ABI устройства, или вам необходимо установить специальные разрешения/секонтекст для некоторых файлов модуля.
|
||||
|
||||
Если вы хотите полностью контролировать и настраивать процесс установки, объявите `SKIPUNZIP=1` в файле `customize.sh`, чтобы пропустить все шаги установки по умолчанию. При этом ваш `customize.sh` будет сам отвечать за установку.
|
||||
|
||||
Сценарий `customize.sh` запускается в оболочке BusyBox `ash` KernelSU с включенным "Автономным режимом". Доступны следующие переменные и функции:
|
||||
|
||||
#### Переменные
|
||||
|
||||
- `KSU` (bool): переменная, отмечающая, что скрипт выполняется в окружении KernelSU, причем значение этой переменной всегда будет true. Ее можно использовать для различения KernelSU и Magisk.
|
||||
- `KSU_VER` (string): строка версии текущего установленного KernelSU (например, `v0.4.0`)
|
||||
- `KSU_VER_CODE` (int): код версии текущего установленного KernelSU в пользовательском пространстве (например, `10672`)
|
||||
- `KSU_KERNEL_VER_CODE` (int): код версии текущей установленной KernelSU в пространстве ядра (например, `10672`)
|
||||
- `BOOTMODE` (bool): в KernelSU всегда должно быть `true`.
|
||||
- `MODPATH` (path): путь, по которому должны быть установлены файлы ваших модулей
|
||||
- `TMPDIR` (path): место, где вы можете временно хранить файлы
|
||||
- `ZIPFILE` (path): установочный zip-архив вашего модуля
|
||||
- `ARCH` (string): архитектура процессора устройства. Значение: `arm`, `arm64`, `x86` или `x64`.
|
||||
- `IS64BIT` (bool): `true`, если `$ARCH` имеет значение `arm64` или `x64`.
|
||||
- `API` (int): уровень API (версия Android) устройства (например, `23` для Android 6.0)
|
||||
|
||||
::: warning
|
||||
В KernelSU MAGISK_VER_CODE всегда равен 25200, а MAGISK_VER всегда равен v25.2. Пожалуйста, не используйте эти две переменные для определения того, запущен ли он на KernelSU или нет.
|
||||
:::
|
||||
|
||||
#### Функции {#functions}
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
вывести <msg> на консоль
|
||||
Избегайте использования 'echo', так как он не будет отображаться в консоли пользовательского recovery
|
||||
|
||||
abort <msg>
|
||||
вывести сообщение об ошибке <msg> на консоль и завершить установку
|
||||
Избегайте использования команды 'exit', так как в этом случае будут пропущены шаги очистки завершения установки
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
если [context] не задан, то по умолчанию используется "u:object_r:system_file:s0".
|
||||
Эта функция является сокращением для следующих команд:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
если [context] не задан, то по умолчанию используется "u:object_r:system_file:s0".
|
||||
для всех файлов в <directory> будет вызвана команда:
|
||||
set_perm file owner group filepermission context
|
||||
для всех каталогов в <directory> (включая себя самого), он вызовет:
|
||||
set_perm dir owner group dirpermission context
|
||||
```
|
||||
|
||||
## Загрузочные сценарии {#boot-scripts}
|
||||
|
||||
В KernelSU скрипты делятся на два типа в зависимости от режима их работы: режим post-fs-data и режим late_start service:
|
||||
|
||||
- режим post-fs-data
|
||||
- Эта стадия является БЛОКИРУЮЩЕЙ. Процесс загрузки приостанавливается до завершения выполнения или по истечении 10 секунд.
|
||||
- Сценарии запускаются до того, как будут смонтированы какие-либо модули. Это позволяет разработчику модулей динамически настраивать свои модули до того, как они будут смонтированы.
|
||||
- Этот этап происходит до запуска Zygote, что практически означает, что все в Android
|
||||
- **ПРЕДУПРЕЖДЕНИЕ:** использование `setprop` приведет к блокировке процесса загрузки! Вместо этого используйте `resetprop -n <prop_name> <prop_value>`.
|
||||
- Запускайте скрипты в этом режиме только в случае необходимости.
|
||||
- режим обслуживания late_start
|
||||
- Эта стадия является НЕБЛОКИРУЮЩЕЙ. Ваш скрипт выполняется параллельно с остальным процессом загрузки.
|
||||
- **Это рекомендуемый этап для запуска большинства скриптов.**
|
||||
|
||||
В KernelSU скрипты запуска делятся на два типа по месту их хранения: общие скрипты и скрипты модулей:
|
||||
|
||||
- Общие скрипты
|
||||
- Размещаются в файлах `/data/adb/post-fs-data.d` или `/data/adb/service.d`.
|
||||
- Выполняется только в том случае, если скрипт установлен как исполняемый (`chmod +x script.sh`)
|
||||
- Скрипты в `post-fs-data.d` выполняются в режиме post-fs-data, а скрипты в `service.d` - в режиме late_start service.
|
||||
- Модули не должны **НЕ** добавлять общие скрипты при установке
|
||||
- Скрипты модуля
|
||||
- Размещаются в отдельной папке модуля
|
||||
- Выполняются только в том случае, если модуль включен
|
||||
- `post-fs-data.sh` запускается в режиме post-fs-data, а `service.sh` - в режиме late_start service.
|
||||
|
||||
Все загрузочные скрипты будут выполняться в оболочке BusyBox `ash` от KernelSU с включенным "Автономным режимом".
|
||||
@@ -1,50 +0,0 @@
|
||||
# Выход из циклической загрузки {#intruduction}
|
||||
|
||||
При прошивке устройства могут возникать ситуации, когда устройство становится "окирпиченным". Теоретически, если использовать fastboot только для прошивки загрузочного раздела или установить неподходящие модули, из-за которых устройство не загружается, то это можно восстановить соответствующими операциями. В данном документе описаны некоторые экстренные методы восстановления работоспособности "окирпиченного" устройства.
|
||||
|
||||
## Кирпич путем перепрошивки загрузочного раздела
|
||||
|
||||
В KernelSU при прошивке загрузочного раздела могут возникнуть следующие ситуации:
|
||||
|
||||
1. Загрузочный образ прошивается в неправильном формате. Например, если формат загрузки телефона - `gz`, а вы прошили образ в формате `lz4`, то телефон не сможет загрузиться.
|
||||
2. Для корректной загрузки телефона необходимо отключить проверку AVB (обычно для этого требуется стереть все данные на телефоне).
|
||||
3. Ядро содержит ошибки или не подходит для прошивки телефона.
|
||||
|
||||
Независимо от ситуации, восстановить работоспособность можно путем **прошивки стокового загрузочного образа**. Поэтому в начале руководства по установке мы настоятельно рекомендуем создать резервную копию стокового загрузочного образа перед прошивкой. Если у вас нет резервной копии, вы можете получить оригинальную заводскую загрузку от других пользователей с таким же устройством, как у вас, или из официальной прошивки.
|
||||
|
||||
## Окирпичивание из-за модулей
|
||||
|
||||
Установка модулей может быть более распространенной причиной окирпичивания устройства, но мы должны серьезно предупредить вас: **Не устанавливайте модули из неизвестных источников**! Поскольку модули обладают правами root, они могут нанести непоправимый ущерб вашему устройству!
|
||||
|
||||
### Нормальные модули
|
||||
|
||||
Если вы прошили модуль, безопасность которого доказана, но он приводит к невозможности загрузки устройства, то такая ситуация легко восстанавливается в KernelSU без каких-либо проблем. KernelSU имеет встроенные механизмы для спасения устройства, в том числе следующие:
|
||||
|
||||
1. Обновление AB
|
||||
2. Восстановление при нажатии клавиши уменьшения громкости
|
||||
|
||||
#### AB-обновление {#ab-update}
|
||||
|
||||
Механизм обновления модулей в KernelSU основан на механизме AB-обновления, используемом в OTA-обновлениях системы Android. При установке нового модуля или обновлении существующего он не будет напрямую изменять текущий файл модуля. Вместо этого все модули будут встроены в другой образ обновления. После перезагрузки системы она попытается начать использовать этот образ обновления. Если система Android успешно загрузится, то модули будут действительно обновлены.
|
||||
|
||||
Поэтому самым простым и наиболее часто используемым методом спасения устройства является **принудительная перезагрузка**. Если после прошивки модуля не удается запустить систему, можно нажать и удерживать кнопку питания более 10 секунд, после чего система автоматически перезагрузится; после перезагрузки произойдет откат к состоянию до обновления модуля, а ранее обновленные модули будут автоматически отключены.
|
||||
|
||||
#### Спасение, с зажатой клавишей уменьшения громкости {#volume-down}
|
||||
|
||||
Если обновление AB не помогло решить проблему, можно попробовать использовать **Безопасный режим**. В безопасном режиме все модули отключены.
|
||||
|
||||
Войти в безопасный режим можно двумя способами:
|
||||
|
||||
1. Встроенный безопасный режим некоторых систем; некоторые системы имеют встроенный безопасный режим, доступ к которому осуществляется долгим нажатием кнопки уменьшения громкости, в то время как другие (например, MIUI) могут включить безопасный режим в Recovery. При входе в безопасный режим системы KernelSU также переходит в безопасный режим и автоматически отключает модули.
|
||||
2. Встроенный безопасный режим KernelSU; метод работы заключается в том, что после первого экрана загрузки необходимо **непрерывно нажать клавишу уменьшения громкости более трех раз**. Обратите внимание, что именно нажать-отпустить, нажать-отпустить, нажать-отпустить, а не нажать и удерживать.
|
||||
|
||||
После входа в безопасный режим все модули на странице модулей менеджера KernelSU Manager отключаются, но можно выполнить операцию "деинсталляция" для удаления модулей, которые могут вызывать проблемы.
|
||||
|
||||
Встроенный безопасный режим реализован в ядре, поэтому вероятность пропуска ключевых событий из-за перехвата исключена. Однако для ядер, отличных от ГКИ, может потребоваться ручная интеграция кода, и за рекомендациями можно обратиться к официальной документации.
|
||||
|
||||
### Вредоносные модули
|
||||
|
||||
Если описанные выше способы не помогли спасти устройство, то высока вероятность того, что установленный модуль имеет вредоносные операции или повредил устройство иным способом. В этом случае есть только два варианта:
|
||||
|
||||
1. Стереть данные и прошить официальную систему.
|
||||
2. Обратиться в сервисную службу.
|
||||
@@ -1,30 +0,0 @@
|
||||
# Неофициально поддерживаемые устройства
|
||||
|
||||
::: warning
|
||||
На этой странице представлены ядра для устройств, не поддерживающих ГКИ и поддерживающих KernelSU, которые поддерживаются другими разработчиками.
|
||||
:::
|
||||
|
||||
::: warning
|
||||
Эта страница предназначена только для поиска исходного кода, соответствующего вашему устройству, и **НЕ** означает, что исходный код был проверен _разработчиками KernelSU_. Вы должны использовать его на свой страх и риск.
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Сопровождающий</th>
|
||||
<th>Репозиторий</th>
|
||||
<th>Поддерживаемое устройство</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# Что такое KernelSU? {#introduction}
|
||||
|
||||
KernelSU - это root-решение для устройств Android GKI, работающее в режиме ядра и предоставляющее root-права пользовательским приложениям непосредственно в пространстве ядра.
|
||||
|
||||
## Особенности {#features}
|
||||
|
||||
Основной особенностью KernelSU является то, что он **основан на ядре**. KernelSU работает в режиме ядра, поэтому он может предоставить интерфейс ядра, которого раньше не было. Например, мы можем добавить аппаратную точку останова любому процессу в режиме ядра; мы можем получить доступ к физической памяти любого процесса без чьего-либо ведома; мы можем перехватить любой syscall в пространстве ядра; и т.д.
|
||||
|
||||
Кроме того, KernelSU предоставляет систему модулей через overlayfs, что позволяет загружать в систему пользовательские плагины. Также предусмотрен механизм модификации файлов в разделе `/system`.
|
||||
|
||||
## Как использовать {#how-to-use}
|
||||
|
||||
Пожалуйста, обратитесь к: [Установка](installation)
|
||||
|
||||
## Как собрать {#how-to-build}
|
||||
|
||||
[Как собрать](how-to-build)
|
||||
|
||||
## Обсуждение {#discussion}
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Основанное на ядре root-решение для Android
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: Основанное на ядре root-решение для Android
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Начало работы
|
||||
link: /ru_RU/guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: Посмотр на GitHub
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: Основанный на ядре
|
||||
details: KernelSU работает в режиме ядра Linux, он имеет больше контроля над пользовательскими приложениями.
|
||||
- title: Контроль доступа по белому списку
|
||||
details: Только приложение, которому предоставлено разрешение root, может получить доступ к `su`, другие приложения не могут воспринимать su.
|
||||
- title: Ограниченные root-права
|
||||
details: KernelSU позволяет вам настраивать uid, gid, группы, возможности и правила SELinux для su. Заприте root-власть в клетке.
|
||||
- title: Модульность и открытый исходный код
|
||||
details: KernelSU поддерживает модификацию /system бессистемно с помощью overlayfs и имеет открытый исходный код под лицензией GPL-3.
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# App Profile
|
||||
|
||||
App Profile là một cơ chế do KernelSU cung cấp để tùy chỉnh cấu hình của các ứng dụng khác nhau.
|
||||
|
||||
Đối với các ứng dụng được cấp quyền root (tức là có thể sử dụng `su`), App Profile cũng có thể được gọi là Root Profile. Nó cho phép tùy chỉnh các quy tắc `uid`, `gid`, `groups`, `capabilities` và `SELinux` của lệnh `su`, do đó hạn chế các đặc quyền của người dùng root. Ví dụ: nó có thể chỉ cấp quyền mạng cho các ứng dụng tường lửa trong khi từ chối quyền truy cập tệp hoặc có thể cấp quyền shell thay vì quyền truy cập root đầy đủ cho các ứng dụng đóng băng: **giữ nguồn điện theo nguyên tắc đặc quyền tối thiểu.**
|
||||
|
||||
Đối với các ứng dụng thông thường không có quyền root, App Profile có thể kiểm soát hành vi của hệ thống kernel và mô-đun đối với các ứng dụng này. Ví dụ, nó có thể xác định liệu các sửa đổi do mô-đun tạo ra có nên được giải quyết hay không. Hệ thống kernel và mô-đun có thể đưa ra quyết định dựa trên cấu hình này, chẳng hạn như thực hiện các hoạt động tương tự như "hiding"
|
||||
|
||||
## Root Profile
|
||||
|
||||
### UID, GID, và Groups
|
||||
|
||||
Hệ thống Linux có hai khái niệm: người dùng (user) và nhóm (group). Mỗi người dùng có một user ID (UID) và một người dùng có thể thuộc nhiều nhóm, mỗi nhóm có group ID (GID) riêng. Những ID này được sử dụng để xác định người dùng trong hệ thống và xác định tài nguyên hệ thống nào họ có thể truy cập.
|
||||
|
||||
Người dùng có UID bằng 0 được gọi là người dùng root và các nhóm có GID bằng 0 được gọi là nhóm root. Nhóm người dùng root thường giữ các đặc quyền hệ thống cao nhất.
|
||||
|
||||
Trong trường hợp hệ thống Android, mỗi ứng dụng là một người dùng riêng biệt (không bao gồm các trường hợp UID dùng chung) với một UID duy nhất. Ví dụ: `0` đại diện cho người dùng root, `1000` đại diện cho `system`, `2000` đại diện cho ADB shell và các UID từ 10000 đến 19999 đại diện cho các ứng dụng thông thường.
|
||||
|
||||
:::info
|
||||
Ở đây, UID được đề cập không giống với khái niệm nhiều người dùng hoặc hồ sơ công việc (Work profile) trong hệ thống Android. Hồ sơ công việc thực sự được triển khai bằng cách phân vùng phạm vi UID. Ví dụ: 10000-19999 đại diện cho người dùng chính, trong khi 110000-119999 đại diện cho hồ sơ công việc. Mỗi ứng dụng thông thường trong số đó đều có UID riêng.
|
||||
:::
|
||||
|
||||
Mỗi ứng dụng có thể có nhiều nhóm, với GID đại diện cho nhóm chính, thường khớp với UID. Các nhóm khác được gọi là nhóm bổ sung. Một số quyền nhất định được kiểm soát thông qua các nhóm, chẳng hạn như quyền truy cập mạng hoặc truy cập Bluetooth.
|
||||
|
||||
Ví dụ: nếu chúng ta thực thi lệnh `id` trong shell ADB, kết quả đầu ra có thể trông như thế này:
|
||||
|
||||
```sh
|
||||
oriole:/ $ id
|
||||
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0
|
||||
```
|
||||
|
||||
Ở đây, UID là `2000` và GID (ID nhóm chính) cũng là `2000`. Ngoài ra, nó thuộc một số nhóm bổ sung, chẳng hạn như `inet` (biểu thị khả năng tạo ổ cắm `AF_INET` và `AF_INET6`) và `sdcard_rw` (biểu thị quyền đọc/ghi đối với thẻ SD).
|
||||
|
||||
Root Profile của KernelSU cho phép tùy chỉnh UID, GID và các nhóm cho quy trình gốc sau khi thực thi `su`. Ví dụ: Cấu hình gốc của ứng dụng gốc có thể đặt UID của nó thành `2000`, có nghĩa là khi sử dụng `su`, các quyền thực tế của ứng dụng sẽ ở cấp shell ADB. Nhóm `inet` có thể bị xóa, ngăn lệnh `su` truy cập mạng.
|
||||
|
||||
:::tip Ghi chú
|
||||
Hồ sơ ứng dụng chỉ kiểm soát các quyền của tiến trình gốc sau khi sử dụng `su`; nó không kiểm soát các quyền của ứng dụng. Nếu một ứng dụng đã yêu cầu quyền truy cập mạng, ứng dụng đó vẫn có thể truy cập mạng ngay cả khi không sử dụng `su`. Việc xóa nhóm `inet` khỏi `su` chỉ ngăn `su` truy cập mạng.
|
||||
:::
|
||||
|
||||
Root Profile được thực thi trong kernel và không dựa vào hành vi tự nguyện của các ứng dụng root, không giống như việc chuyển đổi người dùng hoặc nhóm thông qua `su`, việc cấp quyền `su` hoàn toàn phụ thuộc vào người dùng chứ không phải nhà phát triển.
|
||||
|
||||
### Capabilities
|
||||
|
||||
Capabilities (khả năng) là một cơ chế phân tách đặc quyền trong Linux.
|
||||
|
||||
Với mục đích thực hiện kiểm tra quyền, việc triển khai UNIX truyền thống phân biệt hai loại quy trình: quy trình đặc quyền (có ID người dùng hiệu quả là 0, được gọi là siêu người dùng hoặc root) và quy trình không có đặc quyền (có UID hiệu dụng khác 0). Các quy trình đặc quyền bỏ qua tất cả các bước kiểm tra quyền của kernel, trong khi các quy trình không có đặc quyền phải chịu sự kiểm tra quyền đầy đủ dựa trên thông tin xác thực của quy trình (thường là: UID hiệu quả, GID hiệu quả và danh sách nhóm bổ sung).
|
||||
|
||||
Bắt đầu với Linux 2.2, Linux chia các đặc quyền truyền thống được liên kết với siêu người dùng thành các đơn vị riêng biệt, được gọi là các khả năng, có thể được bật và tắt một cách độc lập.
|
||||
|
||||
Mỗi Khả năng đại diện cho một hoặc nhiều đặc quyền. Ví dụ: `CAP_DAC_READ_SEARCH` thể hiện khả năng bỏ qua việc kiểm tra quyền để đọc tệp cũng như quyền đọc và thực thi thư mục. Nếu người dùng có UID hiệu dụng là `0` (người dùng root) thiếu khả năng `CAP_DAC_READ_SEARCH` hoặc cao hơn, điều này có nghĩa là ngay cả khi họ là root, họ không thể tùy ý đọc tệp.
|
||||
|
||||
Cấu hình gốc của KernelSU cho phép tùy chỉnh các Khả năng của tiến trình gốc sau khi thực thi `su`, nhờ đó đạt được việc cấp một phần "quyền root". Không giống như UID và GID đã nói ở trên, một số ứng dụng gốc nhất định yêu cầu UID là `0` sau khi sử dụng `su`. Trong những trường hợp như vậy, việc giới hạn Khả năng của người dùng root này bằng UID `0` có thể hạn chế các hoạt động được phép của họ.
|
||||
|
||||
:::tip Rất Khuyến Nghị
|
||||
Capabilities của Linux [tài liệu chính thức](https://man7.org/linux/man-pages/man7/capabilities.7.html) cung cấp giải thích chi tiết về các khả năng mà mỗi Capabilities thể hiện. Nếu bạn có ý định tùy chỉnh Capabilities, bạn nên đọc tài liệu này trước.
|
||||
:::
|
||||
|
||||
### SELinux
|
||||
|
||||
SELinux là một cơ chế Kiểm Soát Truy Cập Bắt Buộc (Mandatory Access Control: MAC) mạnh mẽ. Nó hoạt động theo nguyên tắc **từ chối mặc định**: bất kỳ hành động nào không được cho phép rõ ràng đều bị từ chối.
|
||||
|
||||
SELinux có thể chạy ở hai chế độ chung:
|
||||
|
||||
1. Chế độ cho phép (Permissive mode): Các sự kiện từ chối được ghi lại nhưng không được thực thi.
|
||||
2. Chế độ thực thi (Enforcing mode): Các sự kiện từ chối được ghi lại và thực thi.
|
||||
|
||||
:::warning Cảnh báo
|
||||
Các hệ thống Android hiện đại phụ thuộc rất nhiều vào SELinux để đảm bảo an ninh hệ thống tổng thể. Chúng tôi khuyên bạn không nên sử dụng bất kỳ hệ thống tùy chỉnh nào chạy ở "chế độ cho phép" vì nó không mang lại lợi thế đáng kể nào so với hệ thống mở hoàn toàn.
|
||||
:::
|
||||
|
||||
Việc giải thích khái niệm đầy đủ về SELinux rất phức tạp và nằm ngoài phạm vi của tài liệu này. Trước tiên nên hiểu hoạt động của nó thông qua các tài nguyên sau:
|
||||
|
||||
1. [Wikipedia](https://en.wikipedia.org/wiki/Security-Enhanced_Linux)
|
||||
2. [Red Hat: What Is SELinux?](https://www.redhat.com/en/topics/linux/what-is-selinux)
|
||||
3. [ArchLinux: SELinux](https://wiki.archlinux.org/title/SELinux)
|
||||
|
||||
Root Profile của KernelSU cho phép tùy chỉnh ngữ cảnh SELinux của tiến trình gốc sau khi thực thi `su`. Các quy tắc kiểm soát truy cập cụ thể có thể được đặt cho bối cảnh này để cho phép kiểm soát chi tiết hơn các quyền .
|
||||
|
||||
Trong các trường hợp điển hình, khi một ứng dụng thực thi `su`, nó sẽ chuyển quy trình sang miền SELinux với **quyền truy cập không hạn chế**, chẳng hạn như `u:r:su:s0`. Thông qua Root Profile, miền này có thể được chuyển sang miền tùy chỉnh, chẳng hạn như `u:r:app1:s0` và một loạt quy tắc có thể được xác định cho miền này:
|
||||
|
||||
```sh
|
||||
type app1
|
||||
enforce app1
|
||||
typeattribute app1 mlstrustedsubject
|
||||
allow app1 * * *
|
||||
```
|
||||
|
||||
Lưu ý rằng quy tắc `allow app1 * * *` chỉ được sử dụng cho mục đích minh họa. Trong thực tế, quy tắc này không nên được sử dụng rộng rãi vì nó không khác nhiều so với chế độ cho phép.
|
||||
|
||||
### Escalation
|
||||
|
||||
Nếu cấu hình của Root Profile không được đặt đúng cách, một tình huống escalation (leo thang) có thể xảy ra: các hạn chế do Root Profile áp đặt có thể vô tình bị lỗi.
|
||||
|
||||
Ví dụ: nếu bạn cấp quyền root cho người dùng shell ADB (đây là trường hợp phổ biến), sau đó bạn cấp quyền root cho một ứng dụng thông thường nhưng định cấu hình cấu hình gốc của nó bằng UID 2000 (là UID của người dùng shell ADB) , ứng dụng có thể có được quyền truy cập root đầy đủ bằng cách thực hiện lệnh `su` hai lần:
|
||||
|
||||
1. Lần thực thi `su` đầu tiên phải tuân theo sự thực thi của App Profile và sẽ chuyển sang UID `2000` (adb shell) thay vì `0` (root).
|
||||
2. Lần thực thi `su` thứ hai, vì UID là `2000` và bạn đã cấp quyền truy cập root cho UID `2000` (adb shell) trong cấu hình, ứng dụng sẽ có toàn quyền root.
|
||||
|
||||
:::warning Ghi chú
|
||||
Hành vi này hoàn toàn được mong đợi và không phải là lỗi. Vì vậy, chúng tôi khuyến nghị như sau:
|
||||
|
||||
Nếu bạn thực sự cần cấp quyền root cho ADB (ví dụ: với tư cách là nhà phát triển), bạn không nên thay đổi UID thành `2000` khi định cấu hình Root Profile. Sử dụng `1000` (hệ thống) sẽ là lựa chọn tốt hơn.
|
||||
:::
|
||||
|
||||
## Non-Root Profile
|
||||
|
||||
### Umount Modules
|
||||
|
||||
KernelSU cung cấp một cơ chế systemless để sửa đổi các phân vùng hệ thống, đạt được thông qua việc gắn overlayfs. Tuy nhiên, một số ứng dụng có thể nhạy cảm với hành vi đó. Do đó, chúng ta có thể dỡ bỏ các mô-đun được gắn trên các ứng dụng này bằng cách đặt tùy chọn "umount modules".
|
||||
|
||||
Ngoài ra, giao diện cài đặt của trình quản lý KernelSU cung cấp một công tắc cho "umount modules by default". Theo mặc định, công tắc này được **bật**, có nghĩa là KernelSU hoặc một số mô-đun sẽ hủy tải các mô-đun cho ứng dụng này trừ khi áp dụng cài đặt bổ sung. Nếu bạn không thích cài đặt này hoặc nếu nó ảnh hưởng đến một số ứng dụng nhất định, bạn có các tùy chọn sau:
|
||||
|
||||
1. Giữ nút chuyển cho "umount modules by default" và tắt riêng tùy chọn "umount modules" trong App Profile đối với các ứng dụng yêu cầu tải mô-đun (hoạt động như "whitelist").
|
||||
2. Tắt khóa chuyển cho "umount modules by default" và bật riêng tùy chọn "umount modules" trong App Profile cho các ứng dụng yêu cầu dỡ bỏ mô-đun (hoạt động như "blacklist").
|
||||
|
||||
:::info
|
||||
Trong các thiết bị sử dụng kernel phiên bản 5.10 trở lên, kernel thực hiện việc dỡ tải các mô-đun. Tuy nhiên, đối với các thiết bị chạy phiên bản kernel dưới 5.10, công tắc này chỉ đơn thuần là một tùy chọn cấu hình và bản thân KernelSU không thực hiện bất kỳ hành động nào. Một số mô-đun, chẳng hạn như Zygisksu, có thể sử dụng công tắc này để xác định xem có cần thiết phải dỡ bỏ mô-đun hay không.
|
||||
:::
|
||||
@@ -1,28 +0,0 @@
|
||||
# Sự khác biệt với Magisk
|
||||
|
||||
Mặc dù có nhiều điểm tương đồng giữa mô-đun KernelSU và mô-đun Magisk nhưng chắc chắn vẫn có một số khác biệt do cơ chế triển khai hoàn toàn khác nhau của chúng. Nếu muốn mô-đun của mình chạy trên cả Magisk và KernelSU, bạn phải hiểu những khác biệt này.
|
||||
|
||||
## Điểm tương đồng
|
||||
|
||||
- Định dạng file mô-đun: đều sử dụng định dạng zip để sắp xếp các mô-đun và định dạng của các mô-đun gần như giống nhau
|
||||
- Thư mục cài đặt mô-đun: cả hai đều nằm trong `/data/adb/modules`
|
||||
- systemless: cả hai đều hỗ trợ sửa đổi /system theo cách không có hệ thống thông qua các mô-đun
|
||||
- post-fs-data.sh: thời gian thực hiện và ngữ nghĩa hoàn toàn giống nhau
|
||||
- service.sh: thời gian thực hiện và ngữ nghĩa hoàn toàn giống nhau
|
||||
- system.prop: hoàn toàn giống nhau
|
||||
- sepolicy.rule: hoàn toàn giống nhau
|
||||
- BusyBox: các tập lệnh được chạy trong BusyBox với "standalone mode" được bật trong cả hai trường hợp
|
||||
|
||||
## Điểm khác biệt
|
||||
|
||||
Trước khi hiểu sự khác biệt, bạn cần biết cách phân biệt mô-đun của bạn đang chạy trong KernelSU hay Magisk. Bạn có thể sử dụng biến môi trường `KSU` để phân biệt nó ở tất cả những nơi bạn có thể chạy tập lệnh mô-đun (`customize.sh`, `post-fs-data.sh`, `service.sh`). Trong KernelSU, biến môi trường này sẽ được đặt thành `true`.
|
||||
|
||||
Dưới đây là một số khác biệt:
|
||||
|
||||
- Không thể cài đặt các mô-đun KernelSU ở chế độ Recovery.
|
||||
- Các mô-đun KernelSU không có hỗ trợ tích hợp cho Zygisk (nhưng bạn có thể sử dụng các mô-đun Zygisk thông qua [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
- Phương pháp thay thế hoặc xóa file trong module KernelSU hoàn toàn khác với Magisk. KernelSU không hỗ trợ phương thức `.replace`. Thay vào đó, bạn cần tạo một file cùng tên với `mknod filename c 0 0` để xóa file tương ứng.
|
||||
- Các thư mục của BusyBox khác nhau. BusyBox tích hợp trong KernelSU nằm ở `/data/adb/ksu/bin/busybox`, trong khi ở Magisk nó nằm ở `/data/adb/magisk/busybox`. **Lưu ý rằng đây là hoạt động nội bộ của KernelSU và có thể thay đổi trong tương lai!**
|
||||
- KernelSU không hỗ trợ file `.replace`; tuy nhiên, KernelSU hỗ trợ biến `REMOVE` và `REPLACE` để xóa hoặc thay thế các tệp và thư mục.
|
||||
- KernelSU thêm giai đoạn `boot-completed` để chạy một số script khi khởi động xong.
|
||||
- KernelSU thêm giai đoạn `post-mount` để chạy một số tập lệnh sau khi gắn overlayfs
|
||||
@@ -1,67 +0,0 @@
|
||||
# FAQ
|
||||
|
||||
## KernelSU có hỗ trợ thiết bị của tôi không?
|
||||
|
||||
Đầu tiên, thiết bị của bạn sẽ có thể mở khóa bootloader. Nếu không thể thì nó không được hỗ trợ.
|
||||
|
||||
Sau đó, cài đặt Ứng dụng KernelSU manager vào thiết bị của bạn và mở nó, nếu nó hiển thị `Unsupported` thì thiết bị của bạn chưa được hỗ trợ ngay, nhưng bạn có thể tạo nguồn kernel và tích hợp KernelSU để nó hoạt động hoặc sử dụng [unofficially-support-devices](unofficially-support-devices).
|
||||
|
||||
## KernelSU có cần mở khóa Bootloader không?
|
||||
|
||||
Chắc chắn có.
|
||||
|
||||
## KernelSU có hỗ trợ các mô-đun không?
|
||||
|
||||
Có, nhưng đây là phiên bản đầu tiên nên có thể bị lỗi. Đợi nó ổn định nhé :)
|
||||
|
||||
## KernelSU có hỗ trợ Xposed không?
|
||||
|
||||
Có, [Dreamland](https://github.com/canyie/Dreamland) và [TaiChi](https://taichi.cool) hiện đã hoạt động. Đối với LSPosed, bạn có thể làm cho nó hoạt động bằng [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext)
|
||||
|
||||
## KernelSU có hỗ trợ Zygisk không?
|
||||
|
||||
KernelSU không có hỗ trợ Zygisk tích hợp sẵn nhưng thay vào đó, bạn có thể sử dụng [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## KernelSU có tương thích với Magisk không?
|
||||
|
||||
Hệ thống mô-đun của KernelSU xung đột với magic mount của Magisk, nếu có bất kỳ mô-đun nào được kích hoạt trong KernelSU thì toàn bộ Magisk sẽ không hoạt động.
|
||||
|
||||
Nhưng nếu bạn chỉ sử dụng `su` của KernelSU thì nó sẽ hoạt động tốt với Magisk: KernelSU sửa đổi `kernel` và Magisk sửa đổi `ramdisk`, chúng có thể hoạt động cùng nhau.
|
||||
|
||||
## KernelSU sẽ thay thế Magisk?
|
||||
|
||||
Chúng tôi không nghĩ như vậy và đó không phải là mục tiêu của chúng tôi. Magisk đủ tốt cho giải pháp root userspace và nó sẽ tồn tại lâu dài. Mục tiêu của KernelSU là cung cấp giao diện kernel cho người dùng chứ không thay thế Magisk.
|
||||
|
||||
## KernelSU có thể hỗ trợ các thiết bị không phải GKI không?
|
||||
|
||||
Điều đó là có thể. Nhưng bạn nên tải nguồn kernel về và tích hợp KernelSU vào source tree rồi tự biên dịch kernel.
|
||||
|
||||
## KernelSU có thể hỗ trợ các thiết bị dưới Android 12 không?
|
||||
|
||||
Chính kernel của thiết bị ảnh hưởng đến khả năng tương thích của KernelSU và nó không liên quan gì đến phiên bản Android. Hạn chế duy nhất là các thiết bị chạy Android 12 phải là kernel 5.10+(thiết bị GKI). Vì thế:
|
||||
|
||||
1. Các thiết bị chạy Android 12 phải được hỗ trợ.
|
||||
2. Các thiết bị có kernel cũ (Một số thiết bị Android 12 cũng là kernel cũ) tương thích (Bạn nên tự build kernel)
|
||||
|
||||
## KernelSU có thể hỗ trợ kernel cũ không?
|
||||
|
||||
Có thể, KernelSU hiện đã được backport sang kernel 4.14, đối với kernel cũ hơn, bạn cần backport nó một cách cẩn thận và PR rất đáng hoan nghênh!
|
||||
|
||||
## Làm cách nào để tích hợp KernelSU cho kernel cũ?
|
||||
|
||||
Vui lòng tham khảo [hướng dẫn](how-to-integrate-for-non-gki)
|
||||
|
||||
## Tại sao phiên bản Android của tôi là 13 và kernel hiển thị "android12-5.10"?
|
||||
|
||||
Phiên bản Kernel không liên quan gì đến phiên bản Android, nếu bạn cần flash kernel thì dùng luôn phiên bản kernel, phiên bản Android không quá quan trọng.
|
||||
|
||||
## Đã có mount namespace --mount-master/global trên KernelSU chưa?
|
||||
|
||||
Hiện tại thì không (có thể có trong tương lai), nhưng có nhiều cách để chuyển sang global mount namespace một cách thủ công, chẳng hạn như:
|
||||
|
||||
1. `nsenter -t 1 -m sh` để lấy shell trong global mount namespace.
|
||||
2. Thêm `nsenter --mount=/proc/1/ns/mnt` vào lệnh bạn muốn thực thi, sau đó lệnh được thực thi trong global mount namespace. KernelSU cũng [sử dụng cách này](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/shirkneko/zako/mksu/ui/util/KsuCli.kt#L115)
|
||||
|
||||
## Tôi là GKI1.0, tôi có thể sử dụng cái này không?
|
||||
|
||||
GKI1 khác hoàn toàn với GKI2, bạn phải tự biên dịch kernel.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Tính Năng Ẩn
|
||||
|
||||
## .ksurc
|
||||
|
||||
Theo mặc định, `/system/bin/sh` tải `/system/etc/mkshrc`.
|
||||
|
||||
Bạn có thể tạo su tải tệp rc tùy chỉnh bằng cách tạo tệp `/data/adb/ksu/.ksurc`.
|
||||
@@ -1,65 +0,0 @@
|
||||
# Làm thế nào để xây dựng KernelSU?
|
||||
|
||||
Trước tiên, bạn nên đọc tài liệu chính thức của Android để xây dựng kernel:
|
||||
|
||||
1. [Building Kernels](https://source.android.com/docs/setup/build/building-kernels?hl=vi)
|
||||
2. [GKI Release Builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds?hl=vi)
|
||||
|
||||
::: warning
|
||||
Trang này dành cho thiết bị GKI, nếu bạn sử dụng kernel cũ, vui lòng tham khảo [cách tích hợp KernelSU cho kernel cũ](how-to-integrate-for-non-gki)
|
||||
:::
|
||||
|
||||
## Build Kernel
|
||||
|
||||
### Đồng bộ hóa mã nguồn kernel
|
||||
|
||||
```sh
|
||||
repo init -u https://android.googlesource.com/kernel/manifest
|
||||
mv <kernel_manifest.xml> .repo/manifests
|
||||
repo init -m manifest.xml
|
||||
repo sync
|
||||
```
|
||||
|
||||
`<kernel_manifest.xml>` là một tệp kê khai có thể xác định duy nhất một bản dựng, bạn có thể sử dụng tệp kê khai đó để thực hiện một bản dựng có thể dự đoán lại. Bạn nên tải xuống tệp kê khai từ [Google GKI release builds](https://source.android.com/docs/core/architecture/kernel/gki-release-builds?hl=vi)
|
||||
|
||||
### Build
|
||||
|
||||
Trước tiên, vui lòng kiểm tra [tài liệu chính thức](https://source.android.com/docs/setup/build/building-kernels?hl=vi).
|
||||
|
||||
Ví dụ: chúng ta cần xây dựng kernel image aarch64:
|
||||
|
||||
```sh
|
||||
LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
|
||||
```
|
||||
|
||||
Đừng quên thêm cờ `LTO=thin`, nếu không quá trình xây dựng có thể thất bại nếu bộ nhớ máy tính của bạn nhỏ hơn 24Gb.
|
||||
|
||||
Bắt đầu từ Android 13, kernel được xây dựng bởi `bazel`:
|
||||
|
||||
```sh
|
||||
tools/bazel build --config=fast //common:kernel_aarch64_dist
|
||||
```
|
||||
|
||||
## Build Kernel với KernelSU
|
||||
|
||||
Nếu bạn có thể build kernel thành công thì việc xây dựng KernelSU thật dễ dàng, Chọn bất kỳ một lần chạy trong thư mục gốc nguồn Kernel:
|
||||
|
||||
- Thẻ mới nhất (ổn định)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
- nhánh chính (dev)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
- Chọn thẻ (chẳng hạn như v0.5.2)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
Và sau đó build lại kernel và bạn sẽ có được image kernel với KernelSU!
|
||||
@@ -1,176 +0,0 @@
|
||||
# Làm thế nào để tích hợp KernelSU vào thiết bị không sử dụng GKI ?
|
||||
|
||||
KernelSU có thể được tích hợp vào kernel không phải GKI và hiện tại nó đã được backport xuống 4.14, thậm chí cũng có thể chạy trên kernel thấp hơn 4.14.
|
||||
|
||||
Do các kernel không phải GKI bị phân mảnh nên chúng tôi không có cách build thống nhất, vì vậy chúng tôi không thể cung cấp các boot image không phải GKI. Nhưng bạn có thể tự build kernel với KernelSU được tích hợp vào.
|
||||
|
||||
Đầu tiên, bạn phải build được kernel từ nguồn có khả năng boot được , nếu kernel không có mã nguồn mở thì rất khó để chạy KernelSU cho thiết bị của bạn.
|
||||
|
||||
Nếu bạn có thể build kernel khởi động được, có hai cách để tích hợp KernelSU vào mã nguồn kernel:
|
||||
|
||||
1. Tự động với `kprobe`
|
||||
2. Thủ công
|
||||
|
||||
|
||||
## Tích hợp vào kprobe
|
||||
|
||||
KernelSU sử dụng kprobe để thực hiện hook kernel, nếu *kprobe* chạy tốt trong kernel của bạn thì nên sử dụng cách này.
|
||||
|
||||
Đầu tiên, thêm KernelSU vào mã nguồn kernel của bạn:
|
||||
|
||||
- Thẻ mới nhất (ổn định)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
- Nhánh chính (dev)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
- Chọn thẻ (chẳng hạn như v0.5.2)
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2
|
||||
```
|
||||
|
||||
Sau đó, bạn nên kiểm tra xem *kprobe* có được bật trong config của bạn hay không, nếu không, vui lòng thêm các cấu hình sau vào:
|
||||
|
||||
```
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_KPROBE_EVENTS=y
|
||||
```
|
||||
|
||||
Rồi build lại kernel của bạn, KernelSU sẽ hoạt động ok.
|
||||
|
||||
Trong trường hợp kprobe chưa được bật, bạn có thể thêm `CONFIG_MODULES=y` vào kernel config. (Nếu vẫn không có hiệu lực thì hãy sử dụng `make menuconfig` rồi tìm các thành phần khác mà kprobe phụ thuộc).
|
||||
|
||||
Nhưng nếu bạn gặp bootloop khi tích hợp KernelSU thì có khả năng ***kprobe bị hỏng trong kernel***, bạn nên fix lỗi kprobe trong mã nguồn hoặc dùng cách 2.
|
||||
|
||||
## Chỉnh sửa mã nguồn kernel thủ công
|
||||
|
||||
Nếu kprobe không thể hoạt động trong kernel của bạn (có thể là lỗi do upstream hoặc kernel dưới bản 4.8), thì bạn có thể thử cách này:
|
||||
|
||||
Đầu tiên, thêm KernelSU vào mã nguồn kernel của bạn:
|
||||
|
||||
```sh
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
Sau đó, thêm lệnh gọi KernelSU vào mã nguồn kernel, đây là một patch bạn có thể tham khảo:
|
||||
|
||||
```diff
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index ac59664eaecf..bdd585e1d2cc 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1890,11 +1890,14 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+extern bool ksu_execveat_hook __read_mostly;
|
||||
+extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv,
|
||||
+ void *envp, int *flags);
|
||||
+extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
+ void *argv, void *envp, int *flags);
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
+ if (unlikely(ksu_execveat_hook))
|
||||
+ ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags);
|
||||
+ else
|
||||
+ ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags);
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/open.c b/fs/open.c
|
||||
index 05036d819197..965b84d486b8 100644
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -348,6 +348,8 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
+extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
+ int *flags);
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
@@ -355,6 +357,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
*/
|
||||
long do_faccessat(int dfd, const char __user *filename, int mode)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
struct cred *override_cred;
|
||||
struct path path;
|
||||
struct inode *inode;
|
||||
struct vfsmount *mnt;
|
||||
int res;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW;
|
||||
|
||||
+ ksu_handle_faccessat(&dfd, &filename, &mode, NULL);
|
||||
|
||||
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
|
||||
return -EINVAL;
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||
index 650fc7e0f3a6..55be193913b6 100644
|
||||
--- a/fs/read_write.c
|
||||
+++ b/fs/read_write.c
|
||||
@@ -434,10 +434,14 @@ ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_read);
|
||||
|
||||
+extern bool ksu_vfs_read_hook __read_mostly;
|
||||
+extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr,
|
||||
+ size_t *count_ptr, loff_t **pos);
|
||||
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
+ if (unlikely(ksu_vfs_read_hook))
|
||||
+ ksu_handle_vfs_read(&file, &buf, &count, &pos);
|
||||
+
|
||||
if (!(file->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_READ))
|
||||
```
|
||||
```diff
|
||||
diff --git a/fs/stat.c b/fs/stat.c
|
||||
index 376543199b5a..82adcef03ecc 100644
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -148,6 +148,8 @@ int vfs_statx_fd(unsigned int fd, struct kstat *stat,
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_statx_fd);
|
||||
|
||||
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||
+
|
||||
/**
|
||||
* vfs_statx - Get basic and extra attributes by filename
|
||||
* @dfd: A file descriptor representing the base dir for a relative filename
|
||||
@@ -170,6 +172,7 @@ int vfs_statx(int dfd, const char __user *filename, int flags,
|
||||
int error = -EINVAL;
|
||||
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
|
||||
|
||||
+ ksu_handle_stat(&dfd, &filename, &flags);
|
||||
if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||
AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
|
||||
return -EINVAL;
|
||||
```
|
||||
|
||||
Bạn sẽ tìm thấy bốn chức năng trong mã nguồn kernel:
|
||||
|
||||
1. do_faccessat, thường là trong `fs/open.c`
|
||||
2. do_execveat_common, thường nằm trong `fs/exec.c`
|
||||
3. vfs_read, thường nằm trong `fs/read_write.c`
|
||||
4. vfs_statx, thường có trong `fs/stat.c`
|
||||
|
||||
Cuối cùng, chỉnh sửa `KernelSU/kernel/ksu.c` và bỏ `enable_sucompat()` sau đó xây dựng lại kernel của bạn, KernelSU sẽ hoạt động tốt.
|
||||
@@ -1,171 +0,0 @@
|
||||
# Cách cài đặt
|
||||
|
||||
## Kiểm tra xem thiết bị của bạn có được hỗ trợ không
|
||||
|
||||
Tải xuống APP KernelSU manager từ [GitHub Releases](https://github.com/tiann/KernelSU/releases) và cài đặt nó vào thiết bị của bạn:
|
||||
|
||||
- Nếu ứng dụng hiển thị `Unsupported`, nghĩa là **Bạn nên tự biên dịch kernel**, KernelSU sẽ không và không bao giờ cung cấp boot image để bạn flash.
|
||||
- Nếu ứng dụng hiển thị `Not installed` thì thiết bị của bạn đã được KernelSU hỗ trợ chính thức.
|
||||
|
||||
:::info
|
||||
Đối với các thiết bị hiển thị `Unsupported`, đây là [Thiết-bị-hỗ-trợ-không-chính-thức](unofficially-support-devices.md), bạn có thể tự biên dịch kernel.
|
||||
:::
|
||||
|
||||
## Sao lưu stock boot.img
|
||||
|
||||
Trước khi flash, trước tiên bạn phải sao lưu stock boot.img. Nếu bạn gặp phải bootloop (vòng lặp khởi động), bạn luôn có thể khôi phục hệ thống bằng cách quay lại trạng thái khởi động ban đầu bằng fastboot.
|
||||
|
||||
::: warning
|
||||
Việc flash có thể gây mất dữ liệu, hãy đảm bảo thực hiện tốt bước này trước khi chuyển sang bước tiếp theo!! Bạn cũng có thể sao lưu tất cả dữ liệu trên điện thoại nếu cần.
|
||||
:::
|
||||
|
||||
## Kiến thức cần thiết
|
||||
|
||||
### ADB và fastboot
|
||||
|
||||
Theo mặc định, bạn sẽ sử dụng các công cụ ADB và fastboot trong hướng dẫn này, vì vậy nếu bạn không biết về chúng, chúng tôi khuyên bạn nên sử dụng công cụ tìm kiếm để tìm hiểu về chúng trước tiên.
|
||||
|
||||
### KMI
|
||||
|
||||
Kernel Module Interface (KMI), các phiên bản kernel có cùng KMI đều **tương thích** Đây là ý nghĩa của "general" trong GKI; ngược lại, nếu KMI khác thì các kernel này không tương thích với nhau và việc flash kernel image có KMI khác với thiết bị của bạn có thể gây ra bootloop.
|
||||
|
||||
Cụ thể, đối với thiết bị GKI, định dạng phiên bản kernel phải như sau:
|
||||
|
||||
```txt
|
||||
KernelRelease :=
|
||||
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
|
||||
w .x .y -zzz -k -something
|
||||
```
|
||||
|
||||
`w.x-zzz-k` là phiên bản KMI. Ví dụ: nếu phiên bản kernel của thiết bị là `5.10.101-android12-9-g30979850fc20`, thì KMI của nó là `5.10-android12-9`; về mặt lý thuyết, nó có thể khởi động bình thường với các kernel KMI khác.
|
||||
|
||||
::: tip
|
||||
Lưu ý rằng SubLevel trong phiên bản kernel không phải là một phần của KMI! Điều đó có nghĩa là `5.10.101-android12-9-g30979850fc20` có cùng KMI với `5.10.137-android12-9-g30979850fc20`!
|
||||
:::
|
||||
|
||||
### Phiên bản kernel vs Phiên bản Android
|
||||
|
||||
Xin lưu ý: **Phiên bản kernel và phiên bản Android không nhất thiết phải giống nhau!**
|
||||
|
||||
Nếu bạn nhận thấy phiên bản kernel của mình là `android12-5.10.101` nhưng phiên bản hệ thống Android của bạn là Android 13 hoặc phiên bản khác; xin đừng ngạc nhiên, vì số phiên bản của hệ thống Android không nhất thiết phải giống với số phiên bản của kernel Linux; Số phiên bản của kernel Linux nhìn chung nhất quán với phiên bản của hệ thống Android đi kèm với **thiết bị khi nó được xuất xưởng**. Nếu hệ thống Android được nâng cấp sau này, phiên bản kernel thường sẽ không thay đổi. Nếu bạn cần flash, **vui lòng tham khảo phiên bản kernel!!**
|
||||
|
||||
## Giới thiệu
|
||||
|
||||
Có một số phương pháp cài đặt KernelSU, mỗi phương pháp phù hợp với một kịch bản khác nhau, vì vậy vui lòng chọn khi cần.
|
||||
|
||||
1. Cài đặt với Recovery tùy chỉnh (ví dụ TWRP)
|
||||
2. Cài đặt bằng ứng dụng flash kernel, chẳng hạn như Franco Kernel Manager
|
||||
3. Cài đặt thông qua fastboot bằng boot.img do KernelSU cung cấp
|
||||
4. Sửa boot.img theo cách thủ công và cài đặt nó
|
||||
|
||||
## Cài đặt với Recovery tùy chỉnh
|
||||
|
||||
Điều kiện chắc chắn: Thiết bị của bạn phải có Recovery tùy chỉnh, chẳng hạn như TWRP; nếu không hoặc chỉ có Recovery chính thức, hãy sử dụng phương pháp khác.
|
||||
|
||||
Các bước:
|
||||
|
||||
1. Từ [Release page](https://github.com/tiann/KernelSU/releases) của KernelSU, tải xuống gói zip bắt đầu bằng AnyKernel3 phù hợp với phiên bản điện thoại của bạn; ví dụ: phiên bản kernel của điện thoại là `android12-5.10. 66`, thì bạn nên tải xuống tệp `AnyKernel3-android12-5.10.66_yyyy-MM.zip` (trong đó `yyyy` là năm và `MM` là tháng).
|
||||
2. Khởi động lại điện thoại vào TWRP.
|
||||
3. Sử dụng adb để đặt AnyKernel3-*.zip vào điện thoại /sdcard và chọn cài đặt nó trong GUI TWRP; hoặc bạn có thể trực tiếp `adb sideload AnyKernel-*.zip` để cài đặt.
|
||||
|
||||
PS. Phương pháp này phù hợp với mọi cài đặt (không giới hạn cài đặt ban đầu hoặc các nâng cấp tiếp theo), miễn là bạn sử dụng TWRP.
|
||||
|
||||
## Cài đặt bằng Kernel Flasher
|
||||
|
||||
Điều kiện chắc chắn: Thiết bị của bạn phải được root. Ví dụ: bạn đã cài đặt Magisk để root hoặc bạn đã cài đặt phiên bản KernelSU cũ và cần nâng cấp lên phiên bản KernelSU khác; nếu thiết bị của bạn chưa được root, vui lòng thử các phương pháp khác.
|
||||
|
||||
Các bước:
|
||||
|
||||
1. Tải xuống zip AnyKernel3; hãy tham khảo phần *Cài đặt bằng Custom Recovery* để biết hướng dẫn tải xuống.
|
||||
2. Mở Ứng dụng Kernel Flash và sử dụng zip AnyKernel3 được cung cấp để flash.
|
||||
|
||||
Nếu trước đây bạn chưa từng sử dụng Ứng dụng Kernel flash thì sau đây là những ứng dụng phổ biến hơn.
|
||||
|
||||
1. [Kernel Flasher](https://github.com/capntrips/KernelFlasher/releases)
|
||||
2. [Franco Kernel Manager](https://play.google.com/store/apps/details?id=com.franco.kernel)
|
||||
3. [Ex Kernel Manager](https://play.google.com/store/apps/details?id=flar2.exkernelmanager)
|
||||
|
||||
PS. Phương pháp này thuận tiện hơn khi nâng cấp KernelSU và có thể thực hiện mà không cần máy tính (sao lưu trước!). .
|
||||
|
||||
Các bước:
|
||||
|
||||
## Cài đặt bằng boot.img do KernelSU cung cấp
|
||||
|
||||
Phương pháp này không yêu cầu bạn phải có TWRP, cũng như không yêu cầu điện thoại của bạn phải có quyền root; nó phù hợp cho lần cài đặt KernelSU đầu tiên của bạn.
|
||||
|
||||
### Tìm boot.img thích hợp
|
||||
|
||||
KernelSU cung cấp boot.img chung cho các thiết bị GKI và bạn nên chuyển boot.img vào phân vùng boot của thiết bị.
|
||||
|
||||
Bạn có thể tải xuống boot.img từ [GitHub Release](https://github.com/tiann/KernelSU/releases), xin lưu ý rằng bạn nên sử dụng đúng phiên bản boot.img. Ví dụ: nếu thiết bị của bạn hiển thị kernel `android12-5.10.101` , bạn cần tải xuống `android-5.10.101_yyyy-MM.boot-<format>.img`. (Giữ KMI nhất quán!)
|
||||
|
||||
Trong đó `<format>` đề cập đến định dạng nén kernel của boot.img chính thức của bạn, vui lòng kiểm tra định dạng nén kernel của boot.img ban đầu của bạn, bạn nên sử dụng đúng định dạng, ví dụ: `lz4`, `gz`; nếu bạn sử dụng định dạng nén không chính xác, bạn có thể gặp phải bootloop.
|
||||
|
||||
::: info
|
||||
1. Bạn có thể sử dụng magiskboot để lấy định dạng nén của boot ban đầu; Tất nhiên, bạn cũng có thể hỏi những người khác, có kinh nghiệm hơn có cùng kiểu máy với thiết bị của bạn. Ngoài ra, định dạng nén của kernel thường không thay đổi nên nếu bạn khởi động thành công với một định dạng nén nào đó thì bạn có thể thử định dạng đó sau.
|
||||
2. Các thiết bị Xiaomi thường sử dụng `gz` hoặc **uncompressed** (không nén).
|
||||
3. Đối với thiết bị Pixel, hãy làm theo hướng dẫn bên dưới.
|
||||
:::
|
||||
|
||||
### flash boot.img vào thiết bị
|
||||
|
||||
Sử dụng `adb` để kết nối thiết bị của bạn, sau đó thực thi `adb restart bootloader` để vào chế độ fastboot, sau đó sử dụng lệnh này để flash KernelSU:
|
||||
|
||||
```sh
|
||||
fastboot flash boot boot.img
|
||||
```
|
||||
|
||||
::: info
|
||||
Nếu thiết bị của bạn hỗ trợ `fastboot boot`, trước tiên bạn có thể sử dụng `fastboot boot boot.img` để thử sử dụng boot.img để khởi động hệ thống trước. Nếu có điều gì bất ngờ xảy ra, hãy khởi động lại để boot.
|
||||
:::
|
||||
|
||||
### khởi động lại
|
||||
|
||||
Sau khi flash xong bạn nên khởi động lại máy:
|
||||
|
||||
```sh
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
## Vá boot.img theo cách thủ công
|
||||
|
||||
Đối với một số thiết bị, định dạng boot.img không quá phổ biến, chẳng hạn như không `lz4`, `gz` và không nén; điển hình nhất là Pixel, định dạng boot.img của nó là nén `lz4_legacy`, ramdisk có thể là `gz` cũng có thể là nén `lz4_legacy`; tại thời điểm này, nếu bạn trực tiếp flash boot.img do KernelSU cung cấp, điện thoại có thể không khởi động được; Tại thời điểm này, bạn có thể vá boot.img theo cách thủ công để dùng được.
|
||||
|
||||
Nhìn chung có hai phương pháp vá:
|
||||
|
||||
1. [Android-Image-Kitchen](https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/)
|
||||
2. [magiskboot](https://github.com/topjohnwu/Magisk/releases)
|
||||
|
||||
Trong số đó, Android-Image-Kitchen phù hợp để hoạt động trên PC và magiskboot cần sự kết nối của điện thoại di động.
|
||||
|
||||
### Chuẩn bị
|
||||
|
||||
1. Lấy stock boot.img của điện thoại; bạn có thể lấy nó từ nhà sản xuất thiết bị của mình, bạn có thể cần [payload-dumper-go](https://github.com/ssut/payload-dumper-go)
|
||||
2. Tải xuống tệp zip AnyKernel3 do KernelSU cung cấp phù hợp với phiên bản KMI của thiết bị của bạn (bạn có thể tham khảo *Cài đặt với Khôi phục tùy chỉnh*).
|
||||
3. Giải nén gói AnyKernel3 và lấy tệp `Image`, đây là tệp kernel của KernelSU.
|
||||
|
||||
### Sử dụng Android-Image-Kitchen
|
||||
|
||||
1. Tải Android-Image-Kitchen về máy tính.
|
||||
2. Đặt stock boot.img vào thư mục gốc của Android-Image-Kitchen.
|
||||
3. Thực thi `./unpackimg.sh boot.img` tại thư mục gốc của Android-Image-Kitchen, lệnh này sẽ giải nén boot.img và bạn sẽ nhận được một số tệp.
|
||||
4. Thay thế `boot.img-kernel` trong thư mục `split_img` bằng `Image` bạn đã trích xuất từ AnyKernel3 (lưu ý đổi tên thành boot.img-kernel).
|
||||
5. Thực thi `./repackimg.sh` tại thư mục gốc của 在 Android-Image-Kitchen; Và bạn sẽ nhận được một file có tên `image-new.img`; Flash boot.img này bằng fastboot(Tham khảo phần trước).
|
||||
|
||||
### Sử dụng magiskboot
|
||||
|
||||
1. Tải xuống Magisk mới nhất từ [Trang phát hành](https://github.com/topjohnwu/Magisk/releases)
|
||||
2. Đổi tên `Magisk-*(version).apk` thành `Magisk-*.zip` và giải nén nó.
|
||||
3. Đẩy `Magisk-*/lib/arm64-v8a/libmagiskboot.so` vào thiết bị của bạn bằng adb: `adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp /magiskboot`
|
||||
4. Đẩy stock boot.img và Image trong AnyKernel3 vào thiết bị của bạn.
|
||||
5. Nhập thư mục adb shell và cd `/data/local/tmp/`, sau đó `chmod +x magiskboot`
|
||||
6. Nhập adb shell và cd `/data/local/tmp/`, thực thi `./magiskboot unpack boot.img` để giải nén `boot.img`, bạn sẽ nhận được file `kernel`, đây là kernel gốc của bạn.
|
||||
7. Thay thế `kernel` bằng `Image`: `mv -f Image kernel`
|
||||
8. Thực thi `./magiskboot repack boot.img` để đóng gói lại boot img và bạn sẽ nhận được một tệp `new-boot.img`, flash tệp này vào thiết bị bằng fastboot.
|
||||
|
||||
## Các phương pháp khác
|
||||
|
||||
Trên thực tế, tất cả các phương pháp cài đặt này chỉ có một ý tưởng chính, đó là **thay thế kernel gốc bằng kernel do KernelSU cung cấp**; chỉ cần đạt được điều này là có thể cài đặt được; ví dụ, sau đây là các phương pháp có thể khác.
|
||||
|
||||
1. Trước tiên hãy cài đặt Magisk, nhận quyền root thông qua Magisk, sau đó sử dụng flasher kernel để flash trong zip AnyKernel từ KernelSU.
|
||||
2. Sử dụng một số bộ công cụ flash trên PC để flash trong kernel do KernelSU cung cấp.
|
||||
@@ -1,257 +0,0 @@
|
||||
# Hướng dẫn mô-đun
|
||||
|
||||
KernelSU cung cấp một cơ chế mô-đun giúp đạt được hiệu quả sửa đổi thư mục hệ thống trong khi vẫn duy trì tính toàn vẹn của phân vùng system. Cơ chế này thường được gọi là "systemless".
|
||||
|
||||
Cơ chế mô-đun của KernelSU gần giống với Magisk. Nếu bạn đã quen với việc phát triển mô-đun Magisk thì việc phát triển các mô-đun KernelSU cũng rất tương tự. Bạn có thể bỏ qua phần giới thiệu các mô-đun bên dưới và chỉ cần đọc [difference-with-magisk](difference-with-magisk.md).
|
||||
|
||||
## Busybox
|
||||
|
||||
KernelSU cung cấp tính năng nhị phân BusyBox hoàn chỉnh (bao gồm hỗ trợ SELinux đầy đủ). Tệp thực thi được đặt tại `/data/adb/ksu/bin/busybox`. BusyBox của KernelSU hỗ trợ "ASH Standalone Shell Mode" có thể chuyển đổi thời gian chạy. Standalone mode này có nghĩa là khi chạy trong shell `ash` của BusyBox, mọi lệnh sẽ trực tiếp sử dụng applet trong BusyBox, bất kể cái gì được đặt là `PATH`. Ví dụ: các lệnh như `ls`, `rm`, `chmod` sẽ **KHÔNG** sử dụng những gì có trong `PATH` (trong trường hợp Android theo mặc định, nó sẽ là `/system/bin/ls`, ` /system/bin/rm` và `/system/bin/chmod` tương ứng), nhưng thay vào đó sẽ gọi trực tiếp các ứng dụng BusyBox nội bộ. Điều này đảm bảo rằng các tập lệnh luôn chạy trong môi trường có thể dự đoán được và luôn có bộ lệnh đầy đủ cho dù nó đang chạy trên phiên bản Android nào. Để buộc lệnh _not_ sử dụng BusyBox, bạn phải gọi tệp thực thi có đường dẫn đầy đủ.
|
||||
|
||||
Mỗi tập lệnh shell đơn lẻ chạy trong ngữ cảnh của KernelSU sẽ được thực thi trong shell `ash` của BusyBox với standalone mode được bật. Đối với những gì liên quan đến nhà phát triển bên thứ 3, điều này bao gồm tất cả các tập lệnh khởi động và tập lệnh cài đặt mô-đun.
|
||||
|
||||
Đối với những người muốn sử dụng tính năng "Standalone mode" này bên ngoài KernelSU, có 2 cách để kích hoạt tính năng này:
|
||||
|
||||
1. Đặt biến môi trường `ASH_STANDALONE` thành `1`<br>Ví dụ: `ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>`
|
||||
2. Chuyển đổi bằng các tùy chọn dòng lệnh:<br>`/data/adb/ksu/bin/busybox sh -o độc lập <script>`
|
||||
|
||||
Để đảm bảo tất cả shell `sh` tiếp theo được thực thi cũng chạy ở standalone mode, tùy chọn 1 là phương thức ưu tiên (và đây là những gì KernelSU và KernelSU manager sử dụng nội bộ) vì các biến môi trường được kế thừa xuống các tiến trình con.
|
||||
|
||||
::: tip sự khác biệt với Magisk
|
||||
|
||||
BusyBox của KernelSU hiện đang sử dụng tệp nhị phân được biên dịch trực tiếp từ dự án Magisk. **Cảm ơn Magisk!** Vì vậy, bạn không phải lo lắng về vấn đề tương thích giữa các tập lệnh BusyBox trong Magisk và KernelSU vì chúng hoàn toàn giống nhau!
|
||||
:::
|
||||
|
||||
## Mô-đun hạt nhânSU
|
||||
|
||||
Mô-đun KernelSU là một thư mục được đặt trong `/data/adb/modules` với cấu trúc bên dưới:
|
||||
|
||||
```txt
|
||||
/data/adb/modules
|
||||
├── .
|
||||
├── .
|
||||
|
|
||||
├── $MODID <--- Thư mục được đặt tên bằng ID của mô-đun
|
||||
│ │
|
||||
│ │ *** Nhận Dạng Mô-đun ***
|
||||
│ │
|
||||
│ ├── module.prop <--- Tệp này lưu trữ metadata của mô-đun
|
||||
│ │
|
||||
│ │ *** Nội Dung Chính ***
|
||||
│ │
|
||||
│ ├── system <--- Thư mục này sẽ được gắn kết nếu skip_mount không tồn tại
|
||||
│ │ ├── ...
|
||||
│ │ ├── ...
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ │ *** Cờ Trạng Thái ***
|
||||
│ │
|
||||
│ ├── skip_mount <--- Nếu tồn tại, KernelSU sẽ KHÔNG gắn kết thư mục hệ thống của bạn
|
||||
│ ├── disable <--- Nếu tồn tại, mô-đun sẽ bị vô hiệu hóa
|
||||
│ ├── remove <--- Nếu tồn tại, mô-đun sẽ bị xóa trong lần khởi động lại tiếp theo
|
||||
│ │
|
||||
│ │ *** Tệp Tùy Chọn ***
|
||||
│ │
|
||||
│ ├── post-fs-data.sh <--- Tập lệnh này sẽ được thực thi trong post-fs-data
|
||||
│ ├── post-mount.sh <--- Tập lệnh này sẽ được thực thi trong post-mount
|
||||
│ ├── service.sh <--- Tập lệnh này sẽ được thực thi trong dịch vụ late_start
|
||||
│ ├── boot-completed.sh <--- Tập lệnh này sẽ được thực thi khi khởi động xong
|
||||
| ├── uninstall.sh <--- Tập lệnh này sẽ được thực thi khi KernelSU xóa mô-đun của bạn
|
||||
│ ├── system.prop <--- Các thuộc tính trong tệp này sẽ được tải dưới dạng thuộc tính hệ thống bằng resetprop
|
||||
│ ├── sepolicy.rule <--- Quy tắc riêng biệt tùy chỉnh bổ sung
|
||||
│ │
|
||||
│ │ *** Được Tạo Tự Động, KHÔNG TẠO HOẶC SỬA ĐỔI THỦ CÔNG ***
|
||||
│ │
|
||||
│ ├── vendor <--- Một liên kết tượng trưng đến $MODID/system/vendor
|
||||
│ ├── product <--- Một liên kết tượng trưng đến $MODID/system/product
|
||||
│ ├── system_ext <--- Một liên kết tượng trưng đến $MODID/system/system_ext
|
||||
│ │
|
||||
│ │ *** Mọi tập tin / thư mục bổ sung đều được phép ***
|
||||
│ │
|
||||
│ ├── ...
|
||||
│ └── ...
|
||||
|
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
::: tip sự khác biệt với Magisk
|
||||
KernelSU không có hỗ trợ tích hợp cho Zygisk nên không có nội dung liên quan đến Zygisk trong mô-đun. Tuy nhiên, bạn có thể sử dụng [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) để hỗ trợ các mô-đun Zygisk. Trong trường hợp này, nội dung của mô-đun Zygisk giống hệt với nội dung được Magisk hỗ trợ.
|
||||
:::
|
||||
|
||||
### module.prop
|
||||
|
||||
module.prop là tệp cấu hình cho mô-đun. Trong KernelSU, nếu một mô-đun không chứa tệp này, nó sẽ không được nhận dạng là mô-đun. Định dạng của tập tin này như sau:
|
||||
|
||||
```txt
|
||||
id=<string>
|
||||
name=<string>
|
||||
version=<string>
|
||||
versionCode=<int>
|
||||
author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` phải khớp với biểu thức chính quy này: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
ví dụ: ✓ `a_module`, ✓ `a.module`, ✓ `module-101`, ✗ `a module`, ✗ `1_module`, ✗ `-a-module`<br>
|
||||
Đây là **mã định danh duy nhất** của mô-đun của bạn. Bạn không nên thay đổi nó sau khi được xuất bản.
|
||||
- `versionCode` phải là **số nguyên**. Điều này được sử dụng để so sánh các phiên bản
|
||||
- Các chuỗi khác không được đề cập ở trên có thể là chuỗi **một dòng** bất kỳ.
|
||||
- Đảm bảo sử dụng kiểu ngắt dòng `UNIX (LF)` chứ không phải `Windows (CR+LF)` hoặc `Macintosh (CR)`.
|
||||
|
||||
### Tập lệnh Shell
|
||||
|
||||
Vui lòng đọc phần [Boot Scripts](#boot-scripts) để hiểu sự khác biệt giữa `post-fs-data.sh` và `service.sh`. Đối với hầu hết các nhà phát triển mô-đun, `service.sh` sẽ đủ tốt nếu bạn chỉ cần chạy tập lệnh khởi động, nếu bạn cần chạy tập lệnh sau khi khởi động xong, vui lòng sử dụng `boot-completed.sh`. Nếu bạn muốn làm gì đó sau khi gắn các lớp phủ, vui lòng sử dụng `post-mount.sh`.
|
||||
|
||||
Trong tất cả các tập lệnh của mô-đun của bạn, vui lòng sử dụng `MODDIR=${0%/*}` để lấy đường dẫn thư mục cơ sở của mô-đun của bạn; **KHÔNG** mã hóa cứng đường dẫn mô-đun của bạn trong tập lệnh.
|
||||
|
||||
::: tip sự khác biệt với Magisk
|
||||
Bạn có thể sử dụng biến môi trường KSU để xác định xem tập lệnh đang chạy trong KernelSU hay Magisk. Nếu chạy trong KernelSU, giá trị này sẽ được đặt thành true.
|
||||
:::
|
||||
|
||||
### thư mục `system`
|
||||
|
||||
Nội dung của thư mục này sẽ được phủ lên trên phân vùng /system của hệ thống bằng cách sử dụng overlayfs sau khi hệ thống được khởi động. Điều này có nghĩa rằng:
|
||||
|
||||
1. Các file có cùng tên với các file trong thư mục tương ứng trong hệ thống sẽ bị ghi đè bởi các file trong thư mục này.
|
||||
2. Các thư mục có cùng tên với thư mục tương ứng trong hệ thống sẽ được gộp với các thư mục trong thư mục này.
|
||||
|
||||
Nếu bạn muốn xóa một tập tin hoặc thư mục trong thư mục hệ thống gốc, bạn cần tạo một tập tin có cùng tên với tập tin/thư mục trong thư mục mô-đun bằng cách sử dụng `mknod filename c 0 0`. Bằng cách này, hệ thống lớp phủ sẽ tự động "whiteout" (Xóa trắng) tệp này như thể nó đã bị xóa (phân vùng /system không thực sự bị thay đổi).
|
||||
|
||||
Bạn cũng có thể khai báo một biến có tên `REMOVE` chứa danh sách các thư mục trong `customize.sh` để thực hiện các thao tác xóa và KernelSU sẽ tự động thực thi `mknod <TARGET> c 0 0` trong các thư mục tương ứng của mô-đun. Ví dụ:
|
||||
|
||||
```sh
|
||||
REMOVE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
```
|
||||
|
||||
Danh sách trên sẽ thực thi `mknod $MODPATH/system/app/YouTuBe c 0 0` và `mknod $MODPATH/system/app/Bloatware c 0 0`; và `/system/app/YouTube` và `/system/app/Bloatware` sẽ bị xóa sau khi mô-đun này có hiệu lực.
|
||||
|
||||
Nếu bạn muốn thay thế một thư mục trong hệ thống, bạn cần tạo một thư mục có cùng đường dẫn trong thư mục mô-đun của mình, sau đó đặt thuộc tính `setfattr -ntrust.overlay.opaque -v y <TARGET>` cho thư mục này. Bằng cách này, hệ thống Overlayfs sẽ tự động thay thế thư mục tương ứng trong hệ thống (mà không thay đổi phân vùng /system).
|
||||
|
||||
Bạn có thể khai báo một biến có tên `REPLACE` trong tệp `customize.sh` của mình, bao gồm danh sách các thư mục sẽ được thay thế và KernelSU sẽ tự động thực hiện các thao tác tương ứng trong thư mục mô-đun của bạn. Ví dụ:
|
||||
|
||||
REPLACE="
|
||||
/system/app/YouTube
|
||||
/system/app/Bloatware
|
||||
"
|
||||
|
||||
Danh sách này sẽ tự động tạo các thư mục `$MODPATH/system/app/YouTube` và `$MODPATH/system/app/Bloatware`, sau đó thực thi `setfattr -ntrusted.overlay.opaque -v y $MODPATH/system/app/ YouTube` và `setfattr -n Trust.overlay.opaque -v y $MODPATH/system/app/Bloatware`. Sau khi mô-đun có hiệu lực, `/system/app/YouTube` và `/system/app/Bloatware` sẽ được thay thế bằng các thư mục trống.
|
||||
|
||||
::: tip sự khác biệt với Magisk
|
||||
|
||||
Cơ chế không hệ thống của KernelSU được triển khai thông qua các overlayfs của kernel, trong khi Magisk hiện sử dụng magic mount (bind mount). Hai phương pháp triển khai có những khác biệt đáng kể, nhưng mục tiêu cuối cùng đều giống nhau: sửa đổi các tệp /system mà không sửa đổi vật lý phân vùng /system.
|
||||
:::
|
||||
|
||||
Nếu bạn quan tâm đến overlayfs, bạn nên đọc [documentation on overlayfs](https://docs.kernel.org/filesystems/overlayfs.html) của Kernel Linux.
|
||||
|
||||
### system.prop
|
||||
|
||||
Tệp này có cùng định dạng với `build.prop`. Mỗi dòng bao gồm `[key]=[value]`.
|
||||
|
||||
### sepolicy.rule
|
||||
|
||||
Nếu mô-đun của bạn yêu cầu một số bản vá lỗi chính sách bổ sung, vui lòng thêm các quy tắc đó vào tệp này. Mỗi dòng trong tệp này sẽ được coi là một tuyên bố chính sách.
|
||||
|
||||
## Trình cài đặt mô-đun
|
||||
|
||||
Trình cài đặt mô-đun KernelSU là mô-đun KernelSU được đóng gói trong tệp zip có thể được flash trong APP KernelSU manager. Trình cài đặt mô-đun KernelSU đơn giản chỉ là mô-đun KernelSU được đóng gói dưới dạng tệp zip.
|
||||
|
||||
```txt
|
||||
module.zip
|
||||
│
|
||||
├── customize.sh <--- (Tùy chọn, biết thêm chi tiết sau)
|
||||
│ Tập lệnh này sẽ có nguồn gốc từ update-binary
|
||||
├── ...
|
||||
├── ... /* Các tập tin còn lại của mô-đun */
|
||||
│
|
||||
```
|
||||
|
||||
:::warning
|
||||
Mô-đun KernelSU KHÔNG được hỗ trợ để cài đặt trong khôi phục tùy chỉnh!!
|
||||
:::
|
||||
|
||||
### Tùy chỉnh
|
||||
|
||||
Nếu bạn cần tùy chỉnh quá trình cài đặt mô-đun, bạn có thể tùy ý tạo một tập lệnh trong trình cài đặt có tên `customize.sh`. Tập lệnh này sẽ được _sourced_ (không được thực thi!) bởi tập lệnh cài đặt mô-đun sau khi tất cả các tệp được trích xuất và các quyền mặc định cũng như văn bản thứ hai được áp dụng. Điều này rất hữu ích nếu mô-đun của bạn yêu cầu thiết lập bổ sung dựa trên ABI của thiết bị hoặc bạn cần đặt các quyền/văn bản thứ hai đặc biệt cho một số tệp mô-đun của mình.
|
||||
|
||||
Nếu bạn muốn kiểm soát và tùy chỉnh hoàn toàn quá trình cài đặt, hãy khai báo `SKIPUNZIP=1` trong `customize.sh` để bỏ qua tất cả các bước cài đặt mặc định. Bằng cách đó, `customize.sh` của bạn sẽ chịu trách nhiệm cài đặt mọi thứ.
|
||||
|
||||
Tập lệnh `customize.sh` chạy trong shell `ash` BusyBox của KernelSU với "Chế độ độc lập" được bật. Có sẵn các biến và hàm sau:
|
||||
|
||||
#### Biến
|
||||
|
||||
- `KSU` (bool): biến để đánh dấu script đang chạy trong môi trường KernelSU, và giá trị của biến này sẽ luôn đúng. Bạn có thể sử dụng nó để phân biệt giữa KernelSU và Magisk.
|
||||
- `KSU_VER` (chuỗi): chuỗi phiên bản của KernelSU được cài đặt hiện tại (ví dụ: `v0.4.0`)
|
||||
- `KSU_VER_CODE` (int): mã phiên bản của KernelSU được cài đặt hiện tại trong không gian người dùng (ví dụ: `10672`)
|
||||
- `KSU_KERNEL_VER_CODE` (int): mã phiên bản của KernelSU được cài đặt hiện tại trong không gian kernel (ví dụ: `10672`)
|
||||
- `BOOTMODE` (bool): luôn là `true` trong KernelSU
|
||||
- `MODPATH` (đường dẫn): đường dẫn nơi các tập tin mô-đun của bạn sẽ được cài đặt
|
||||
- `TMPDIR` (đường dẫn): nơi bạn có thể lưu trữ tạm thời các tập tin
|
||||
- `ZIPFILE` (đường dẫn): zip cài đặt mô-đun của bạn
|
||||
- `ARCH` (chuỗi): kiến trúc CPU của thiết bị. Giá trị là `arm`, `arm64`, `x86` hoặc `x64`
|
||||
- `IS64BIT` (bool): `true` nếu `$ARCH` là `arm64` hoặc `x64`
|
||||
- `API` (int): cấp độ API (phiên bản Android) của thiết bị (ví dụ: `23` cho Android 6.0)
|
||||
|
||||
::: warning
|
||||
Trong KernelSU, MAGISK_VER_CODE luôn là 25200 và MAGISK_VER luôn là v25.2. Vui lòng không sử dụng hai biến này để xác định xem nó có chạy trên KernelSU hay không.
|
||||
:::
|
||||
|
||||
#### Hàm
|
||||
|
||||
```txt
|
||||
ui_print <msg>
|
||||
in <msg> ra console
|
||||
Tránh sử dụng 'echo' vì nó sẽ không hiển thị trong console của recovery tùy chỉnh
|
||||
|
||||
abort <msg>
|
||||
in thông báo lỗi <msg> ra bàn điều khiển và chấm dứt cài đặt
|
||||
Tránh sử dụng 'exit' vì nó sẽ bỏ qua các bước dọn dẹp chấm dứt
|
||||
|
||||
set_perm <target> <owner> <group> <permission> [context]
|
||||
nếu [context] không được đặt, mặc định là "u:object_r:system_file:s0"
|
||||
chức năng này là một shorthand cho các lệnh sau:
|
||||
chown owner.group target
|
||||
chmod permission target
|
||||
chcon context target
|
||||
|
||||
set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
|
||||
nếu [context] không được đặt, mặc định là "u:object_r:system_file:s0"
|
||||
đối với tất cả các tệp trong <directory>, nó sẽ gọi:
|
||||
bối cảnh cấp phép tệp của nhóm chủ sở hữu tệp set_perm
|
||||
đối với tất cả các thư mục trong <directory> (bao gồm cả chính nó), nó sẽ gọi:
|
||||
set_perm bối cảnh phân quyền của nhóm chủ sở hữu thư mục
|
||||
```
|
||||
|
||||
## Tập lệnh khởi động
|
||||
|
||||
Trong KernelSU, tập lệnh được chia thành hai loại dựa trên chế độ chạy của chúng: chế độ post-fs-data và chế độ dịch vụ late_start:
|
||||
|
||||
- chế độ post-fs-data
|
||||
- Giai đoạn này là BLOCKING. Quá trình khởi động bị tạm dừng trước khi thực thi xong hoặc đã trôi qua 10 giây.
|
||||
- Các tập lệnh chạy trước khi bất kỳ mô-đun nào được gắn kết. Điều này cho phép nhà phát triển mô-đun tự động điều chỉnh các mô-đun của họ trước khi nó được gắn kết.
|
||||
- Giai đoạn này xảy ra trước khi Zygote được khởi động, điều này gần như có ý nghĩa đối với mọi thứ trong Android
|
||||
- **CẢNH BÁO:** sử dụng `setprop` sẽ làm quá trình khởi động bị nghẽn! Thay vào đó, vui lòng sử dụng `resetprop -n <prop_name> <prop_value>`.
|
||||
- **Chỉ chạy tập lệnh ở chế độ này nếu cần thiết.**
|
||||
- chế độ dịch vụ late_start
|
||||
- Giai đoạn này là NON-BLOCKING. Tập lệnh của bạn chạy song song với phần còn lại của quá trình khởi động.
|
||||
- **Đây là giai đoạn được khuyến nghị để chạy hầu hết các tập lệnh.**
|
||||
|
||||
Trong KernelSU, tập lệnh khởi động được chia thành hai loại dựa trên vị trí lưu trữ của chúng: tập lệnh chung và tập lệnh mô-đun:
|
||||
|
||||
- Kịch Bản Chung
|
||||
- Được đặt trong `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` hoặc `/data/adb/boot- đã hoàn thành.d`
|
||||
- Chỉ được thực thi nếu tập lệnh được đặt là có thể thực thi được (`chmod +x script.sh`)
|
||||
- Các tập lệnh trong `post-fs-data.d` chạy ở chế độ post-fs-data và các tập lệnh trong `service.d` chạy ở chế độ dịch vụ late_start.
|
||||
- Các mô-đun **KHÔNG** thêm các tập lệnh chung trong quá trình cài đặt
|
||||
- Tập Lệnh Mô-đun
|
||||
- Được đặt trong thư mục riêng của mô-đun
|
||||
- Chỉ thực hiện nếu mô-đun được kích hoạt
|
||||
- `post-fs-data.sh` chạy ở chế độ post-fs-data, `service.sh` chạy ở chế độ dịch vụ late_start, `boot-completed.sh` chạy khi khởi động xong, `post-mount.sh` chạy trên overlayfs được gắn kết.
|
||||
|
||||
Tất cả các tập lệnh khởi động sẽ chạy trong shell `ash` BusyBox của KernelSU với "Standalone Mode" được bật.
|
||||
@@ -1,50 +0,0 @@
|
||||
# Cứu khỏi bootloop (Vòng lặp khởi động)
|
||||
|
||||
Khi flash một thiết bị, chúng ta có thể gặp phải tình trạng máy "bị brick". Về lý thuyết, nếu bạn chỉ sử dụng fastboot để flash phân vùng boot hoặc cài đặt các mô-đun không phù hợp khiến máy không khởi động được thì điều này có thể được khắc phục bằng các thao tác thích hợp. Tài liệu này nhằm mục đích cung cấp một số phương pháp khẩn cấp để giúp bạn khôi phục từ thiết bị "bị brick".
|
||||
|
||||
## Brick bởi flash vào phân vùng boot
|
||||
|
||||
Trong KernelSU, các tình huống sau có thể gây ra lỗi khởi động khi flash phân vùng khởi động:
|
||||
|
||||
1. Bạn flash image boot sai định dạng. Ví dụ: nếu định dạng khởi động điện thoại của bạn là `gz`, nhưng bạn flash image định dạng `lz4` thì điện thoại sẽ không thể khởi động.
|
||||
2. Điện thoại của bạn cần tắt xác minh AVB để khởi động bình thường (thường yêu cầu xóa tất cả dữ liệu trên điện thoại).
|
||||
3. Kernel của bạn có một số lỗi hoặc không phù hợp để flash điện thoại của bạn.
|
||||
|
||||
Bất kể tình huống thế nào, bạn có thể khôi phục bằng cách **flash boot image gốc**. Do đó, khi bắt đầu hướng dẫn cài đặt, chúng tôi thực sự khuyên bạn nên sao lưu boot image gốc trước khi flash. Nếu chưa sao lưu, bạn có thể lấy boot image gốc từ người dùng khác có cùng thiết bị với bạn hoặc từ chương trình cơ sở chính thức (official firmware).
|
||||
|
||||
## Brick bởi mô-đun
|
||||
|
||||
Việc cài đặt mô-đun có thể là nguyên nhân phổ biến hơn khiến thiết bị của bạn bị brick, nhưng chúng tôi phải nghiêm túc cảnh báo bạn: **Không cài đặt mô-đun từ các nguồn không xác định**! Vì các mô-đun có đặc quyền root nên chúng có thể gây ra thiệt hại không thể khắc phục cho thiết bị của bạn!
|
||||
|
||||
### Mô-đun bình thường
|
||||
|
||||
Nếu bạn đã flash một mô-đun đã được chứng minh là an toàn nhưng khiến thiết bị của bạn không khởi động được thì tình huống này có thể dễ dàng phục hồi trong KernelSU mà không phải lo lắng gì. KernelSU có các cơ chế tích hợp sẵn để giải cứu thiết bị của bạn, bao gồm:
|
||||
|
||||
1. Cập nhật AB
|
||||
2. Cứu bằng cách nhấn Giảm âm lượng
|
||||
|
||||
#### Cập nhật AB
|
||||
|
||||
Các bản cập nhật mô-đun của KernelSU lấy cảm hứng từ cơ chế cập nhật AB của hệ thống Android được sử dụng trong các bản cập nhật OTA. Nếu bạn cài đặt một mô-đun mới hoặc cập nhật mô-đun hiện có, nó sẽ không trực tiếp sửa đổi tệp mô-đun hiện đang sử dụng. Thay vào đó, tất cả các mô-đun sẽ được tích hợp vào một hình ảnh cập nhật khác. Sau khi hệ thống được khởi động lại, nó sẽ cố gắng bắt đầu sử dụng hình ảnh cập nhật này. Nếu hệ thống Android khởi động thành công, các mô-đun sẽ được cập nhật thực sự.
|
||||
|
||||
Vì vậy, phương pháp đơn giản và được sử dụng phổ biến nhất để cứu thiết bị của bạn là **buộc khởi động lại**. Nếu bạn không thể khởi động hệ thống của mình sau khi flash một mô-đun, bạn có thể nhấn và giữ nút nguồn trong hơn 10 giây và hệ thống sẽ tự động khởi động lại; sau khi khởi động lại, nó sẽ quay trở lại trạng thái trước khi cập nhật mô-đun và các mô-đun được cập nhật trước đó sẽ tự động bị tắt.
|
||||
|
||||
#### Cứu bằng cách nhấn Giảm âm lượng
|
||||
|
||||
Nếu bản cập nhật AB vẫn không giải quyết được vấn đề, bạn có thể thử sử dụng **Chế độ an toàn**. Ở Chế độ an toàn, tất cả các mô-đun đều bị tắt.
|
||||
|
||||
Có hai cách để vào Chế độ an toàn:
|
||||
|
||||
1. Chế Độ An Toàn tích hợp (built-in Safe Mode) của một số hệ thống; một số hệ thống có Chế độ an toàn tích hợp có thể được truy cập bằng cách nhấn và giữ nút giảm âm lượng, trong khi những hệ thống khác (chẳng hạn như MIUI) có thể bật Chế Độ An Toàn trong Recovery. Khi vào Chế Độ An Toàn của hệ thống, KernelSU cũng sẽ vào Chế Độ An Toàn và tự động tắt các mô-đun.
|
||||
2. Chế Độ An Toàn tích hợp (built-in Safe Mode) của KernelSU; phương pháp thao tác là **nhấn phím giảm âm lượng liên tục hơn ba lần** sau màn hình khởi động đầu tiên. Lưu ý là nhấn-thả, nhấn-thả, nhấn-thả chứ không phải nhấn giữ.
|
||||
|
||||
Sau khi vào chế độ an toàn, tất cả các mô-đun trên trang mô-đun của KernelSU Manager đều bị tắt nhưng bạn có thể thực hiện thao tác "gỡ cài đặt" để gỡ cài đặt bất kỳ mô-đun nào có thể gây ra sự cố.
|
||||
|
||||
Chế độ an toàn tích hợp được triển khai trong kernel, do đó không có khả năng thiếu các sự kiện chính do bị chặn. Tuy nhiên, đối với các hạt nhân không phải GKI, có thể cần phải tích hợp mã thủ công và bạn có thể tham khảo tài liệu chính thức để được hướng dẫn.
|
||||
|
||||
### Mô-đun độc hại
|
||||
|
||||
Nếu các phương pháp trên không thể cứu được thiết bị của bạn thì rất có thể mô-đun bạn cài đặt có hoạt động độc hại hoặc đã làm hỏng thiết bị của bạn thông qua các phương tiện khác. Trong trường hợp này, chỉ có hai gợi ý:
|
||||
|
||||
1. Xóa sạch dữ liệu và flash hệ thống chính thức.
|
||||
2. Tham khảo dịch vụ hậu mãi.
|
||||
@@ -1,32 +0,0 @@
|
||||
# Thiết bị hỗ trợ không chính thức
|
||||
|
||||
::: warning
|
||||
Đây là trang liệt kê kernel cho các thiết bị không dùng GKI được hỗ trợ bởi các lập trình viên khác.
|
||||
|
||||
:::
|
||||
|
||||
::: warning
|
||||
Trang này chỉ để cho bạn tìm thấy source cho thiết bị của bạn, nó **HOÀN TOÀN KHÔNG** được review bởi _lập trình viên của KernelSU_. Vậy nên hãy chấp nhận rủi ro khi sử dụng chúng.
|
||||
|
||||
:::
|
||||
|
||||
<script setup>
|
||||
import data from '../../repos.json'
|
||||
</script>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Người bảo trì</th>
|
||||
<th>Kho lưu trữ</th>
|
||||
<th>Thiết bị hỗ trợ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="repo in data" :key="repo.devices">
|
||||
<td><a :href="repo.maintainer_link" target="_blank" rel="noreferrer">{{ repo.maintainer }}</a></td>
|
||||
<td><a :href="repo.kernel_link" target="_blank" rel="noreferrer">{{ repo.kernel_name }}</a></td>
|
||||
<td>{{ repo.devices }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,21 +0,0 @@
|
||||
# KernelSU là gì?
|
||||
|
||||
KernelSU là một giải pháp root cho các thiết bị Android GKI, nó hoạt động ở chế độ kernel và cấp quyền root cho ứng dụng không gian người dùng trực tiếp trong không gian kernel.
|
||||
|
||||
## Tính năng
|
||||
|
||||
Tính năng chính của KernelSU là **Kernel-based** (dựa trên Kernel). KernelSU hoạt động ở chế độ kernel nên nó có thể cung cấp giao diện kernel mà chúng ta chưa từng có trước đây. Ví dụ: chúng ta có thể thêm điểm dừng phần cứng vào bất kỳ quy trình nào ở chế độ kernel; Chúng ta có thể truy cập bộ nhớ vật lý của bất kỳ quy trình nào mà không bị phát hiện; Chúng ta còn có thể chặn bất kỳ syscall nào trong không gian kernel; v.v.
|
||||
|
||||
Ngoài ra, KernelSU còn cung cấp hệ thống mô-đun thông qua lớp phủ, cho phép bạn tải plugin tùy chỉnh vào hệ thống. Nó cũng cung cấp một cơ chế để sửa đổi các tập tin trong phân vùng `/system`.
|
||||
|
||||
## Hướng dẫn sử dụng
|
||||
|
||||
Xin hãy xem: [Cách cài đặt](installation)
|
||||
|
||||
## Cách để build
|
||||
|
||||
[Cách để build](how-to-build)
|
||||
|
||||
## Thảo luận
|
||||
|
||||
- Telegram: [@KernelSU](https://t.me/KernelSU)
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
layout: home
|
||||
title: Giải pháp root dựa trên kernel dành cho Android
|
||||
|
||||
hero:
|
||||
name: KernelSU
|
||||
text: Giải pháp root dựa trên kernel dành cho Android
|
||||
tagline: ""
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: KernelSU
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Bắt Đầu
|
||||
link: /guide/what-is-kernelsu
|
||||
- theme: alt
|
||||
text: Xem trên GitHub
|
||||
link: https://github.com/tiann/KernelSU
|
||||
|
||||
features:
|
||||
- title: Dựa trên Kernel
|
||||
details: KernelSU đang hoạt động ở chế độ kernel Linux, nó có nhiều quyền kiểm soát hơn đối với các ứng dụng userspace.
|
||||
- title: Kiểm soát truy cập bằng whitelist
|
||||
details: Chỉ ứng dụng được cấp quyền root mới có thể truy cập `su`, các ứng dụng khác không thể nhận được su.
|
||||
- title: Quyền root bị hạn chế
|
||||
details: KernelSU cho phép bạn tùy chỉnh uid, gid, group, capabilities và các quy tắc SELinux của su. Giới hạn sức mạnh của root.
|
||||
- title: Mô-đun & Nguồn mở
|
||||
details: KernelSU hỗ trợ sửa đổi /system một cách systemless bằng overlayfs và nó có nguồn mở theo GPL-3.
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# App Profile
|
||||
|
||||
App Profile 是 KernelSU 提供的一种针对各种应用自定义其使用配置的机制。
|
||||
|
||||
对授予了 root 权限(也即可以使用 `su`)的应用来说,App Profile 也可以称之为 Root Profile,它可以自定义 `su` 的 `uid`, `gid`, `groups`, `capabilities` 以及 `SELinux` 规则,从而限制 root 用户的权限;比如可以针对防火墙应用仅授予网络权限,而不授予文件访问权限,针对冻结类应用仅授予 shell 权限而不是直接给 root;通过最小化权限原则**把权力关进笼子里**。
|
||||
|
||||
对于没有被授予 root 权限的普通应用,App Profile 可以控制内核以及模块系统对此应用的行为;比如是否需要针对此应用卸载模块造成的修改等。内核和模块系统可以通过此配置决定是否要做一些类似“隐藏痕迹”类的操作。
|
||||
|
||||
## Root Profile
|
||||
|
||||
### UID、GID 和 groups
|
||||
|
||||
Linux 系统中有用户和组两个概念。每个用户都有一个用户 ID(UID),一个用户可以属于多个组,每个组也有组 ID(GID)。该 ID 用于识别系统的用户并确定用户可以访问哪些系统资源。
|
||||
|
||||
UID 为 0 的用户被称之为 root 用户,GID 为 0 的组被称之为 root 组;root 用户组通常拥有系统的最高权限。
|
||||
|
||||
对于 Android 系统来说,每一个 App 都是一个单独的用户(不考虑 share uid 的情况),拥有一个唯一的 UID。比如 `0` 是 root 用户,`1000` 是 `system`,`2000` 是 ADB shell,10000-19999 的是普通用户。
|
||||
|
||||
:::info
|
||||
此处的 UID 跟 Android 系统的多用户,或者说工作资料(Work Profile),不是一个概念。工作资料实际上是对 UID 进行分片实现的,比如 10000-19999 是主用户,110000-119999 是工作资料;他们中的任何一个普通应用都拥有自己独有的 UID。
|
||||
:::
|
||||
|
||||
每一个 App 可以有若干个组,GID 是其主要的组,通常与 UID 一致;其他的组被称之为补充组 (groups)。某些权限是通过组控制的,比如网络访问,蓝牙等。
|
||||
|
||||
例如,如果我们在 ADB shell 中执行 `id` 命令,会得到如下输出:
|
||||
|
||||
```sh
|
||||
oriole:/ $ id
|
||||
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0
|
||||
```
|
||||
|
||||
其中,UID 为 `2000`,GID 也即主要组 ID 也为 `2000`;除此之外它还在很多补充组里面,例如 `inet` 组代表可以创建 `AF_INET` 和 `AF_INET6` 的 socket(访问网络),`sdcard_rw` 代表可以读写 sdcard 等。
|
||||
|
||||
KernelSU 的 Root Profile 可以自定义执行 `su` 后 root 进程的 UID, GID 和 groups。例如,你可以设置某个 root 应用的 Root Profile 其 UID 为 `2000`,这意味着此应用在使用 `su` 的时候,它的实际权限是 ADB Shell 级别;你可以去掉 groups 中的 `inet`,这样这个 `su` 就无法访问网络。
|
||||
|
||||
:::tip 注意
|
||||
App Profile 仅仅是控制 root 应用使用 `su` 后的权限,它并非控制 App 本身的权限!如果 App 本身申请了网络访问权限,那么它即使不使用 `su` 也可以访问网络;为 `su` 去掉 `inet` 组仅仅是让 `su` 无法访问网络。
|
||||
:::
|
||||
|
||||
与应用通过 `su` 主动切换用户或者组不同,Root Profile 是在内核中强制实施的,不依赖 root 应用的自觉行为,`su` 权限的授予完全取决于用户而非开发者。
|
||||
|
||||
### Capabilities
|
||||
|
||||
Capabilities 是 Linux 的一种分权机制。
|
||||
|
||||
传统的 UNIX 系统为了执行权限检查,将进程分为两类:特权进程(其有效用户 ID 为 0,称为超级用户或 root)和非特权进程(其有效 UID 为非零)。特权进程会绕过所有内核权限检查,而非特权进程则根据其凭据(通常是有效 UID、有效 GID 和补充组列表)进行完整的权限检查。
|
||||
|
||||
从 Linux 2.2 开始,Linux 将传统上与超级用户关联的特权分解为独立的单元,称为 Capabilities(有的也翻译为“权能”),它们可以独立启用和禁用。
|
||||
|
||||
每一个 Capability 代表一个或者一类权限。比如 `CAP_DAC_READ_SEARCH` 就代表是否有能力绕过文件读取权限检查和目录读取和执行权限检查。如果一个有效 UID 为 `0` 的用户(root 用户)没有 `CAP_DAC_READ_SEARCH` 或者更高 Capalities,这意味着即使它是 root 也不能随意读取文件。
|
||||
|
||||
KernelSU 的 Root Profile 可以自定义执行 `su` 后 root 进程的 Capabilities,从而实现只授予“部分 root 权限”。与上面介绍的 UID, GID 不同,某些 root 应用就是需要 `su` 后 UID 是 `0`,此时我们可以通过限制这个 UID 为 `0` 的 root 用户的 Capabilities,就可以限制它能够执行的操作。
|
||||
|
||||
:::tip 强烈建议
|
||||
Linux 系统关于 Capability 的 [官方文档](https://man7.org/linux/man-pages/man7/capabilities.7.html),解释了每一项 Capability 所代表的能力,写的非常详细,如果你想要自定义 Capabilities,请务必先阅读此文档。
|
||||
:::
|
||||
|
||||
### SELinux
|
||||
|
||||
SELinux 是一种强大的强制性权限访问控制(MAC)机制。它按照**默认拒绝**的原则运行:任何未经明确允许的行为都会被拒绝。
|
||||
|
||||
SELinux 可按两种全局模式运行:
|
||||
|
||||
1. 宽容模式:权限拒绝事件会被记录下来,但不会被强制执行。
|
||||
2. 强制模式:权限拒绝事件会被记录下来**并**强制执行。
|
||||
|
||||
:::warning 警告
|
||||
现代的 Android 系统极度依赖 SELinux 来保障整个系统的安全性,我们强烈建议您不要使用任何以“宽容模式”运行的自定义系统,因为那样与裸奔没什么区别。
|
||||
:::
|
||||
|
||||
SELinux 的完整概念比较复杂,我们这里不打算讲解它的具体工作方式,建议你先通过以下资料来了解其工作原理:
|
||||
|
||||
1. [wikipedia](https://en.wikipedia.org/wiki/Security-Enhanced_Linux)
|
||||
2. [Redhat: what-is-selinux](https://www.redhat.com/en/topics/linux/what-is-selinux)
|
||||
3. [ArchLinux: SELinux](https://wiki.archlinux.org/title/SELinux)
|
||||
|
||||
KernelSU 的 Root Profile 可以自定义执行 `su` 后 root 进程的 SELinux context,并且可以针对这个 context 设置特定的访问控制规则,从而更加精细化地控制 root 权限。
|
||||
|
||||
通常情况下,应用执行 `su` 后,会将进程切换到一个 **不受任何限制** 的 SELinux 域,比如 `u:r:su:s0`,通过 Root Profile,我们可以将它切换到一个自定义的域,比如 `u:r:app1:s0`,然后为这个域制定一系列规则:
|
||||
|
||||
```sh
|
||||
type app1
|
||||
enforce app1
|
||||
typeattribute app1 mlstrustedsubject
|
||||
allow app1 * * *
|
||||
```
|
||||
|
||||
注意:此处的 `allow app1 * * *` 仅仅作为演示方便而使用,实际过程中不应使用这个规则,因为它跟 permissive 区别不大。
|
||||
|
||||
### 逃逸
|
||||
|
||||
如果 Root Profile 的配置不合理,那么可能会发生逃逸的情况:Root Profile 的限制会意外失效。
|
||||
|
||||
比如,如果你为 ADB shell 用户设置允许 root 权限(这是相当常见的情况);然后你给某个普通应用允许 root 权限,但是配置它的 root profile 中的 UID 为 2000(ADB shell 用户的 UID);那么此时,这个 App 可以通过执行两次 `su` 来获得完整的 root 权限:
|
||||
|
||||
1. 第一次执行 `su`,由于 App Profile 强制生效,会正常切换到 UID 为 `2000(adb shell)` 而非 `0(root)`。
|
||||
2. 第二次执行 `su`,由于此时它 UID 是 `2000`,而你给 `2000(adb shell)` 配置了允许 root,它会获得完整的 root 权限!
|
||||
|
||||
:::warning 注意
|
||||
这是完全符合预期的行为,并非 BUG!因此我们建议:
|
||||
|
||||
如果你的确需要给 adb 授予 root 权限(比如你是开发者),那么不建议你在配置 Root Profile 的时候将 UID 改成 `2000`,用 `1000(system)` 会更好。
|
||||
:::
|
||||
|
||||
## Non Root Profile
|
||||
|
||||
### 卸载模块
|
||||
|
||||
KernelSU 提供了一种 systemless 的方式来修改系统分区,这是通过挂载 overlayfs 来实现的。但有些情况下,App 可能会对这种行为比较敏感;因此,我们可以通过设置“卸载模块”来卸载挂载在这些 App 上的模块。
|
||||
|
||||
另外,KernelSU 管理器的设置界面还提供了一个“默认卸载模块”的开关,这个开关默认情况下是**开启**的,这意味着**如果不对 App 做额外的设置**,默认情况下 KernelSU 或者某些模块会对此 App 执行卸载操作。当然,如果你不喜欢这个设置或者这个设置会影响某些 App,可以有如下选择:
|
||||
|
||||
1. 保持“默认卸载模块”的开关,然后针对不需要“卸载模块”的 App 进行单独的设置,在 App Profile 中关闭“卸载模块”;(相当于“白名单”)。
|
||||
2. 关闭“默认卸载模块”的开关,然后针对需要“卸载模块”的 App 进行单独的设置,在 App Profile 中开启“卸载模块”;(相当于“黑名单”)。
|
||||
|
||||
:::info
|
||||
KernelSU 在 5.10 及以上内核上,内核会执行“卸载模块”的操作;但在 5.10 以下的设备上,这个开关仅仅是一个“配置项”,KernelSU 本身不会做任何动作,一些模块(如 Zygisksu 会通过这个模块决定是否需要卸载)
|
||||
:::
|
||||
@@ -1,28 +0,0 @@
|
||||
# KernelSU 模块与 Magisk 的差异 {#title}
|
||||
|
||||
虽然 KernelSU 模块与 Magisk 模块有很多相似之处,但由于它们的实现机制完全不同,因此不可避免地会有一些差异;如果你希望你的模块能同时在 Magisk 与 KernelSU 中运行,那么你必须了解这些差异。
|
||||
|
||||
## 相同之处 {#similarities}
|
||||
|
||||
- 模块文件格式: 都以 zip 的方式组织模块,并且模块的格式几乎相同
|
||||
- 模块安装目录: 都在 `/data/adb/modules`
|
||||
- systemless: 都支持通过模块的形式以 systemless 修改 /system
|
||||
- `post-fs-data.sh`: 执行时机完全一致,语义也完全一致
|
||||
- `service.sh`: 执行时机完全一致,语义也完全一致
|
||||
- `system.prop`: 完全相同
|
||||
- `sepolicy.rule`: 完全相同
|
||||
- BusyBox:脚本都在 BusyBox 中以“独立模式”运行
|
||||
|
||||
## 不同之处 {#differences}
|
||||
|
||||
在了解不同之处之前,你需要知道如何区分你的模块是运行在 KernelSU 还是运行在 Magisk 之中;在所有你可以运行模块脚本的地方(`customize.sh`, `post-fs-data.sh`, `service.sh`),你都可以通过环境变量`KSU` 来区分,在 KernelSU 中,这个环境变量将被设置为 `true`。
|
||||
|
||||
以下是一些不同之处:
|
||||
|
||||
1. KernelSU 的模块不支持在 Recovery 中安装。
|
||||
2. KernelSU 的模块没有内置的 Zygisk 支持(但你可以通过 [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) 来使用 Zygisk 模块)。
|
||||
3. KernelSU 模块替换或者删除文件与 Magisk 完全不同。KernelSU 不支持 `.replace` 方式,相反,你需要通过 `mknod filename c 0 0` 创建同名文件夹来删除对应文件。
|
||||
4. BusyBox 的目录不同;KernelSU 内置的 BusyBox 在 `/data/adb/ksu/bin/busybox` 而 Magisk 在 `/data/adb/magisk/busybox`;**注意此为 KernelSU 内部行为,未来可能会更改!**
|
||||
5. KernelSU 不支持 `.replace` 文件;但 KernelSU 支持 `REPLACE` 和 `REMOVE` 变量。
|
||||
6. KernelSU 新增了一种脚本 `boot-completed.sh`,以便在 Android 系统启动后运行某些任务。
|
||||
7. KernelSU 新增了一种脚本 `post-mount.sh`,以便在 Overlayfs 挂载后运行某些任务。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user