Merge some files and rewrite the update history
This commit is contained in:
@@ -20,7 +20,7 @@ Before understanding the differences, it's important to know how to identify whe
|
||||
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).
|
||||
- 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.
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
|
||||
## Does KernelSU support my device?
|
||||
|
||||
KernelSU supports devices running Android with an unlocked bootloader. However, official support is only for GKI Linux Kernels 5.10+ (in practice, this means your device needs to have Android 12 out-of-the-box to be supported).
|
||||
First, your devices should be able to unlock the bootloader. If not, then there is unsupported.
|
||||
|
||||
You can easily check the support for your device through the KernelSU manager, which is available [here](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
If the app shows `Not installed`, it means your device is officially supported by KernelSU.
|
||||
|
||||
If the app shows `Unsupported`, it means your device isn't officially supported at present. However, you can build kernel source code and integrate KernelSU to make it work, or use [Unofficially supported devices](unofficially-support-devices).
|
||||
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?
|
||||
|
||||
@@ -16,15 +12,15 @@ Certainly, yes.
|
||||
|
||||
## Does KernelSU support modules?
|
||||
|
||||
Yes, most Magisk modules work on KernelSU. Check [Module guide](module.md) for more info.
|
||||
Yes, check [Module guide](module.md).
|
||||
|
||||
## Does KernelSU support Xposed?
|
||||
|
||||
Yes, you can use LSPosed (or other modern Xposed derivative) with [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
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 a module like [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) to support it.
|
||||
KernelSU has no built-in Zygisk support, but you can use [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## Is KernelSU compatible with Magisk?
|
||||
|
||||
@@ -69,7 +65,7 @@ We don't recommend that you modify the system partition directly. Please check [
|
||||
|
||||
## Can KernelSU modify hosts? How can I use AdAway?
|
||||
|
||||
Of course. But KernelSU doesn't have built-in hosts support, you can install a module like [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) to do it.
|
||||
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?
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ If you can successfully build the kernel, adding support for KernelSU will be re
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
|
||||
```
|
||||
|
||||
```sh[main branch (dev)]
|
||||
```sh[ main branch (dev)]
|
||||
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main
|
||||
```
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ author=<string>
|
||||
description=<string>
|
||||
```
|
||||
|
||||
- `id` has to match this regular expression: `^[a-zA-Z][a-zA-Z0-9._-]+$`<br>
|
||||
- `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.
|
||||
@@ -150,7 +150,7 @@ REPLACE="
|
||||
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.
|
||||
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).
|
||||
@@ -250,8 +250,8 @@ In KernelSU, scripts are divided into two types based on their running mode: pos
|
||||
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`).
|
||||
- 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
|
||||
|
||||
@@ -60,7 +60,7 @@ KernelSU は現在カーネル4.14にバックポートされていますが、
|
||||
今はまだありませんが(将来的にはあるかもしれません)、グローバルマウントの名前空間に手動で切り替える方法は、以下のようにたくさんあります:
|
||||
|
||||
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/me/weishu/kernelsu/ui/util/KsuCli.kt#L115) もできます。
|
||||
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 なのですが、使えますか?
|
||||
|
||||
|
||||
@@ -1,118 +1,118 @@
|
||||
# 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 (Permissive): Os eventos de negação são registrados, mas não aplicados.
|
||||
2. Modo impondo (Enforcing): 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 usada 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` (sistema) 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.
|
||||
:::
|
||||
# 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 +1,28 @@
|
||||
# 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.
|
||||
# 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,82 +1,78 @@
|
||||
# Perguntas frequentes
|
||||
|
||||
## KernelSU oferece suporte ao meu dispositivo?
|
||||
|
||||
O KernelSU suporta dispositivos rodando Android com bootloader desbloqueado. No entanto, o suporte oficial é apenas para kernels Linux GKI 5.10+ (na prática isso significa que seu dispositivo precisa ter Android 12 de fábrica para ser compatível).
|
||||
|
||||
Você pode verificar facilmente o suporte para o seu dispositivo através do gerenciador do KernelSU, que está disponível [aqui](https://github.com/tiann/KernelSU/releases).
|
||||
|
||||
Se o app mostrar `Não instalado`, significa que seu dispositivo é oficialmente suportado pelo KernelSU.
|
||||
|
||||
Se o app mostrar `Sem suporte`, significa que seu dispositivo não é oficialmente suportado no momento. No entanto, você pode compilar o código-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, a maioria dos módulos Magisk funcionam no KernelSU. Verifique [Guias de módulo](module.md) para mais informações.
|
||||
|
||||
## KernelSU suporta Xposed?
|
||||
|
||||
Sim, você pode usar LSPosed (ou outro derivado moderno do Xposed) com [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext).
|
||||
|
||||
## KernelSU suporta Zygisk?
|
||||
|
||||
KernelSU não tem suporte integrado ao Zygisk, mas você pode usar um módulo como [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) para suportá-lo.
|
||||
|
||||
## 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 um módulo como [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.
|
||||
# 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,71 +1,71 @@
|
||||
# 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 main (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!
|
||||
# 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 +1,377 @@
|
||||
# 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.
|
||||
# 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 +1,280 @@
|
||||
# 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`.
|
||||
# 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,326 +1,326 @@
|
||||
# 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> (incluindo ele mesmo), 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).
|
||||
# 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 +1,50 @@
|
||||
# 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.
|
||||
# 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 +1,30 @@
|
||||
# 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>
|
||||
# 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 +1,21 @@
|
||||
# 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)
|
||||
# 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 +1,28 @@
|
||||
---
|
||||
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.
|
||||
---
|
||||
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.
|
||||
|
||||
@@ -60,7 +60,7 @@ KernelSU не имеет встроенной поддержки Zygisk, но в
|
||||
Сейчас нет (возможно, в будущем), но есть много способов переключиться на глобальное пространство имен монтирования вручную, например:
|
||||
|
||||
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/me/weishu/kernelsu/ui/util/KsuCli.kt#L115)
|
||||
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, могу ли я использовать это?
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Phiên bản Kernel không liên quan gì đến phiên bản Android, nếu b
|
||||
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/me/weishu/kernelsu/ui/util/KsuCli.kt#L115)
|
||||
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?
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ GKI1 與 GKI2 完全不同,所以您需要自行編譯核心。
|
||||
目前沒有 (未來可能會支援),但實際上有很多種方法手動進入全域命名空間,無需 `su` 內建支援,比如:
|
||||
|
||||
1. `nsenter -t 1 -m sh` 可以取得一個全域 mount namespace 的 shell.
|
||||
2. 在您要執行的命令前新增 `nsenter --mount=/proc/1/ns/mnt` 即可使此命令在全域 mount namespace 下執行。KernelSU 本身也使用了 [這種方法](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt#L115)
|
||||
2. 在您要執行的命令前新增 `nsenter --mount=/proc/1/ns/mnt` 即可使此命令在全域 mount namespace 下執行。KernelSU 本身也使用了 [這種方法](https://github.com/tiann/KernelSU/blob/77056a710073d7a5f7ee38f9e77c9fd0b3256576/manager/app/src/main/java/shirkneko/zako/mksu/ui/util/KsuCli.kt#L115)
|
||||
|
||||
## KernelSU 可以修改 Hosts 嗎? 我要怎麼使用 AdAway?
|
||||
當然。但是 KernelSU 沒有內建的 Hosts 支持,您可以安裝 [systemless-hosts](https://github.com/symbuzzer/systemless-hosts-KernelSU-module) 來做到這一點。
|
||||
|
||||
@@ -29,121 +29,121 @@
|
||||
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz#105e84ad9d1a31d3fb86ba20dc890eefe1a313a0"
|
||||
integrity sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==
|
||||
|
||||
"@algolia/client-abtesting@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.20.3.tgz#e4120919292c57270546cdf8f7030ac8f035c9a2"
|
||||
integrity sha512-wPOzHYSsW+H97JkBLmnlOdJSpbb9mIiuNPycUCV5DgzSkJFaI/OFxXfZXAh1gqxK+hf0miKue1C9bltjWljrNA==
|
||||
"@algolia/client-abtesting@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.20.2.tgz#e0d950735cbe4e00960418749839820a333f9df0"
|
||||
integrity sha512-IS8JSFsDD33haaKIIFaL7qj3bEIG9GldZfb3ILW0QF3at7TcrIJYy58hrDvFee5T3p3E2aH/+wqIr0eha8jB/w==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/client-analytics@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.20.3.tgz#242d448ee34667a52bf1efe5c39b58546d71201f"
|
||||
integrity sha512-XE3iduH9lA7iTQacDGofBQyIyIgaX8qbTRRdj1bOCmfzc9b98CoiMwhNwdTifmmMewmN0EhVF3hP8KjKWwX7Yw==
|
||||
"@algolia/client-analytics@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.20.2.tgz#b8bc4ff50c3968e58b11a56ce50e8732c056ca19"
|
||||
integrity sha512-k0KxCfcX/HZySqPasKy6GkiiDuebaMh2v/nE0HHg1PbsyeyagLapDi6Ktjkxhz8NlUq6eTJR+ddGJegippKQtQ==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/client-common@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.20.3.tgz#7eec522ca18ae446b775092d17d47eecf97c6af9"
|
||||
integrity sha512-IYRd/A/R3BXeaQVT2805lZEdWo54v39Lqa7ABOxIYnUvX2vvOMW1AyzCuT0U7Q+uPdD4UW48zksUKRixShcWxA==
|
||||
"@algolia/client-common@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.20.2.tgz#4a80baedbe739ae84fde300a1f539508e5ae38a7"
|
||||
integrity sha512-xoZcL/Uu49KYDb3feu2n06gALD17p5CslO8Zk3mZ7+uTurK3lgjLws7LNetZ172Ap/GpzPCRXI83d2iDoYQD6Q==
|
||||
|
||||
"@algolia/client-insights@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.20.3.tgz#1bcd9e3090512d3f32e64c2c0b839c7ebfd40574"
|
||||
integrity sha512-QGc/bmDUBgzB71rDL6kihI2e1Mx6G6PxYO5Ks84iL3tDcIel1aFuxtRF14P8saGgdIe1B6I6QkpkeIddZ6vWQw==
|
||||
"@algolia/client-insights@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.20.2.tgz#cf1c21e2c40c3751276c27048c72a3b164b0a4f2"
|
||||
integrity sha512-fy7aCbo9y7WHt/9G03EYc471Dd5kIaM8PNP4z6AEQYr9a9X8c4inwNs6tePxAEfRHwVQi0CZ7kuVdn6/MjWx1A==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/client-personalization@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.20.3.tgz#ca1fe559112bd9aedefa38ca712d69b0bc2bfddf"
|
||||
integrity sha512-zuM31VNPDJ1LBIwKbYGz/7+CSm+M8EhlljDamTg8AnDilnCpKjBebWZR5Tftv/FdWSro4tnYGOIz1AURQgZ+tQ==
|
||||
"@algolia/client-personalization@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.20.2.tgz#ab8342c1e5f1a4ae71383dffdb25910c5df9d06e"
|
||||
integrity sha512-ocL1ZXulfuXzJAwsKw2kMscKMD0rs/f4CFYu6Gjh4mK4um6rGfa1a6u1MSc4swFqRQer0wNP9Pi+kVfKhuKt5A==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/client-query-suggestions@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.20.3.tgz#fed613ab3c7e0be1cb5dcca09fdab65de17e2800"
|
||||
integrity sha512-Nn872PuOI8qzi1bxMMhJ0t2AzVBqN01jbymBQOkypvZHrrjZPso3iTpuuLLo9gi3yc/08vaaWTAwJfPhxPwJUw==
|
||||
"@algolia/client-query-suggestions@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.20.2.tgz#fc2d5836aaf90fba60fc347e0f1b1e8e4ab15592"
|
||||
integrity sha512-Xjs4Tj1zkLCnmq1ys8RRhLQPy002I6GuT/nbHVdSQmQu4yKCI0gOFbwxHdM6yYPEuE3cJx7A4wSQjCH21mUKsg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/client-search@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.20.3.tgz#d8ce41dea173112d4a971d697f34145a1354befd"
|
||||
integrity sha512-9+Fm1ahV8/2goSIPIqZnVitV5yHW5E5xTdKy33xnqGd45A9yVv5tTkudWzEXsbfBB47j9Xb3uYPZjAvV5RHbKA==
|
||||
"@algolia/client-search@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.20.2.tgz#941788be5c238197d30a21237e0b3f28d80db874"
|
||||
integrity sha512-2cD3RGB5byusLS0DAX1Nvl5MLiv7OoGgQrRs+94dTalqjvK8lGKzxxJhXoVojgx2qcROyIUAIDXFdTqv6NIHaA==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/ingestion@1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.20.3.tgz#32283c2cde45d47b6731bbaaa170703ddf9c3874"
|
||||
integrity sha512-5GHNTiZ3saLjTNyr6WkP5hzDg2eFFAYWomvPcm9eHWskjzXt8R0IOiW9kkTS6I6hXBwN5H9Zna5mZDSqqJdg+g==
|
||||
"@algolia/ingestion@1.20.2":
|
||||
version "1.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.20.2.tgz#f506af644979974a6842fb75ac90df8782da4b0d"
|
||||
integrity sha512-S593Kmhc98+5zdzGet4GrZEBEBGl4vVtqg/MPfW8dCRf9qDRNYSkhBsIzlhQe9JWiohe9oB9LW5meibwOgRmww==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/monitoring@1.20.3":
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.20.3.tgz#8165d8fbb89134876e9055f3432a3de72dc150bc"
|
||||
integrity sha512-KUWQbTPoRjP37ivXSQ1+lWMfaifCCMzTnEcEnXwAmherS5Tp7us6BAqQDMGOD4E7xyaS2I8pto6WlOzxH+CxmA==
|
||||
"@algolia/monitoring@1.20.2":
|
||||
version "1.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.20.2.tgz#920ce38c5d2250bc34692bc256b622e72c3f8169"
|
||||
integrity sha512-bW41aWLYgBv/coJUIT85mkN3kk1VBKsM8tlwB5S/s446Mgc7r8t5TX7kA8kCR2UbwDedOK51i/85/x/rM0ZXbg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/recommend@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.20.3.tgz#bfe36b49287cdf07ad5369640dd65f4b12117e30"
|
||||
integrity sha512-oo/gG77xTTTclkrdFem0Kmx5+iSRFiwuRRdxZETDjwzCI7svutdbwBgV/Vy4D4QpYaX4nhY/P43k84uEowCE4Q==
|
||||
"@algolia/recommend@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.20.2.tgz#423ebaddf13de43a8eb28b0642b60e85f3393e34"
|
||||
integrity sha512-wBMf3J1L5ogvU8p8ifHkknDXWn1zdZ2epkqpt2MkUaZynE3G77rrFU9frcO+Pu1FQJQ5xCDTKcYUUcJCDD00rg==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
"@algolia/requester-browser-xhr@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.20.3.tgz#7bc054eb70669e601e0b1ab034d360eb44c900b6"
|
||||
integrity sha512-BkkW7otbiI/Er1AiEPZs1h7lxbtSO9p09jFhv3/iT8/0Yz0CY79VJ9iq+Wv1+dq/l0OxnMpBy8mozrieGA3mXQ==
|
||||
"@algolia/requester-browser-xhr@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.20.2.tgz#ec674ae20e9fecde1c1a73c5cb0fcfacd3803bac"
|
||||
integrity sha512-w+VMzOkIq2XDGg6Ybzr74RlBZvJQnuIdKpVusQSXCXknvxwAwbO457LmoavhZWl06Lcsk9YDx1X2k0zb+iJQmw==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
|
||||
"@algolia/requester-fetch@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.20.3.tgz#e280a3bd142984a31b172743119f21a3ccef576b"
|
||||
integrity sha512-eAVlXz7UNzTsA1EDr+p0nlIH7WFxo7k3NMxYe8p38DH8YVWLgm2MgOVFUMNg9HCi6ZNOi/A2w/id2ZZ4sKgUOw==
|
||||
"@algolia/requester-fetch@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.20.2.tgz#13d59d9c946d9cd3de319865d70db64e255028e4"
|
||||
integrity sha512-wpjnbvbi3A13b0DvijE45DRYDvwcP5Ttz7RTMkPWTkF1s6AHuo6O2UcwGyaogMAGa1QOOzFYfp5u4YQwMOQx5g==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
|
||||
"@algolia/requester-node-http@5.20.3":
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.20.3.tgz#cf06a8568efd7f3ad02414e13f2fa94c15edfc37"
|
||||
integrity sha512-FqR3pQPfHfQyX1wgcdK6iyqu86yP76MZd4Pzj1y/YLMj9rRmRCY0E0AffKr//nrOFEwv6uY8BQY4fd9/6b0ZCg==
|
||||
"@algolia/requester-node-http@5.20.2":
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.20.2.tgz#29bd7333dbec0d24dfecd2e1d8276fe40e67ea9d"
|
||||
integrity sha512-YuSSdtgUt1dFBTNYUb+2TA5j0Hd0eDXE0bVISjUvTCqmoaGsGLwW+rKI7p1eLQ1r7RESwBAvUwcY1qP2Wl3Lyw==
|
||||
dependencies:
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
|
||||
"@babel/helper-string-parser@^7.25.9":
|
||||
version "7.25.9"
|
||||
@@ -156,16 +156,16 @@
|
||||
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
|
||||
|
||||
"@babel/parser@^7.25.3":
|
||||
version "7.26.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.9.tgz#d9e78bee6dc80f9efd8f2349dcfbbcdace280fd5"
|
||||
integrity sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==
|
||||
version "7.26.8"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.8.tgz#deca2b4d99e5e1b1553843b99823f118da6107c2"
|
||||
integrity sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.26.9"
|
||||
"@babel/types" "^7.26.8"
|
||||
|
||||
"@babel/types@^7.26.9":
|
||||
version "7.26.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.9.tgz#08b43dec79ee8e682c2ac631c010bdcac54a21ce"
|
||||
integrity sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==
|
||||
"@babel/types@^7.26.8":
|
||||
version "7.26.8"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.8.tgz#97dcdc190fab45be7f3dc073e3c11160d677c127"
|
||||
integrity sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.25.9"
|
||||
"@babel/helper-validator-identifier" "^7.25.9"
|
||||
@@ -309,9 +309,9 @@
|
||||
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
|
||||
|
||||
"@iconify-json/simple-icons@^1.2.21":
|
||||
version "1.2.25"
|
||||
resolved "https://registry.yarnpkg.com/@iconify-json/simple-icons/-/simple-icons-1.2.25.tgz#b984e1851baac5cddbe82ecc15f3a5806c8879bb"
|
||||
integrity sha512-2E1/gOCO97rF6usfhhiXxwzCb+UhdEsxW3lW1Sew+xZY0COY6dp82Z/r1rUt2fWKneWjuoGcNeJHHXQyG8mIuw==
|
||||
version "1.2.24"
|
||||
resolved "https://registry.yarnpkg.com/@iconify-json/simple-icons/-/simple-icons-1.2.24.tgz#1cc703e731f979f76b0586236b402372169062d5"
|
||||
integrity sha512-06ZWXZx3PHCE+02zn+iIGOKKNgE3kyPd0Yh7IUEIa0bCYI6UmGlsYYghRx8As9TnTNYMCEiy5V0zI4Jb6EY6XA==
|
||||
dependencies:
|
||||
"@iconify/types" "*"
|
||||
|
||||
@@ -325,114 +325,102 @@
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz#731df27dfdb77189547bcef96ada7bf166bbb2fb"
|
||||
integrity sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==
|
||||
"@rollup/rollup-android-arm-eabi@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz#9b726b4dcafb9332991e9ca49d54bafc71d9d87f"
|
||||
integrity sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz#4bea6db78e1f6927405df7fe0faf2f5095e01343"
|
||||
integrity sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==
|
||||
"@rollup/rollup-android-arm64@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz#88326ff46168a47851077ca0bf0c442689ec088f"
|
||||
integrity sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz#a7aab77d44be3c44a20f946e10160f84e5450e7f"
|
||||
integrity sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==
|
||||
"@rollup/rollup-darwin-arm64@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz#b8fbcc9389bc6fad3334a1d16dbeaaa5637c5772"
|
||||
integrity sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz#c572c024b57ee8ddd1b0851703ace9eb6cc0dd82"
|
||||
integrity sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==
|
||||
"@rollup/rollup-darwin-x64@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz#1aa2bcad84c0fb5902e945d88822e17a4f661d51"
|
||||
integrity sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==
|
||||
|
||||
"@rollup/rollup-freebsd-arm64@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz#cf74f8113b5a83098a5c026c165742277cbfb88b"
|
||||
integrity sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==
|
||||
"@rollup/rollup-freebsd-arm64@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz#29c54617e0929264dcb6416597d6d7481696e49f"
|
||||
integrity sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==
|
||||
|
||||
"@rollup/rollup-freebsd-x64@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz#39561f3a2f201a4ad6a01425b1ff5928154ecd7c"
|
||||
integrity sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==
|
||||
"@rollup/rollup-freebsd-x64@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz#a8b58ab7d31882559d93f2d1b5863d9e4b4b2678"
|
||||
integrity sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz#980d6061e373bfdaeb67925c46d2f8f9b3de537f"
|
||||
integrity sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz#a844e1978c8b9766b169ecb1cb5cc0d8a3f05930"
|
||||
integrity sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz#f91a90f30dc00d5a64ac2d9bbedc829cd3cfaa78"
|
||||
integrity sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz#6b44c3b7257985d71b087fcb4ef01325e2fff201"
|
||||
integrity sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz#fac700fa5c38bc13a0d5d34463133093da4c92a0"
|
||||
integrity sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==
|
||||
"@rollup/rollup-linux-arm64-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz#ebb499cf1720115256d0c9ae7598c90cc2251bc5"
|
||||
integrity sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz#f50ecccf8c78841ff6df1706bc4782d7f62bf9c3"
|
||||
integrity sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==
|
||||
"@rollup/rollup-linux-arm64-musl@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz#9658221b59d9e5643348f9a52fa5ef35b4dc07b1"
|
||||
integrity sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==
|
||||
|
||||
"@rollup/rollup-linux-loongarch64-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz#5869dc0b28242da6553e2b52af41374f4038cd6e"
|
||||
integrity sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==
|
||||
"@rollup/rollup-linux-loongarch64-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz#19418cc57579a5655af2d850a89d74b3f7e9aa92"
|
||||
integrity sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz#5cdd9f851ce1bea33d6844a69f9574de335f20b1"
|
||||
integrity sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz#fe0bce7778cb6ce86898c781f3f11369d1a4952c"
|
||||
integrity sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz#ef5dc37f4388f5253f0def43e1440ec012af204d"
|
||||
integrity sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz#9c158360abf6e6f7794285642ba0898c580291f6"
|
||||
integrity sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz#7dbc3ccbcbcfb3e65be74538dfb6e8dd16178fde"
|
||||
integrity sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==
|
||||
"@rollup/rollup-linux-s390x-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz#f9113498d22962baacdda008b5587d568b05aa34"
|
||||
integrity sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz#5783fc0adcab7dc069692056e8ca8d83709855ce"
|
||||
integrity sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==
|
||||
"@rollup/rollup-linux-x64-gnu@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz#aec8d4cdf911cd869a72b8bd00833cb426664e0c"
|
||||
integrity sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz#00b6c29b298197a384e3c659910b47943003a678"
|
||||
integrity sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==
|
||||
"@rollup/rollup-linux-x64-musl@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz#61c0a146bdd1b5e0dcda33690dd909b321d8f20f"
|
||||
integrity sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz#cbfee01f1fe73791c35191a05397838520ca3cdd"
|
||||
integrity sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==
|
||||
"@rollup/rollup-win32-arm64-msvc@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz#c6c5bf290a3a459c18871110bc2e7009ce35b15a"
|
||||
integrity sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz#95cdbdff48fe6c948abcf6a1d500b2bd5ce33f62"
|
||||
integrity sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==
|
||||
"@rollup/rollup-win32-ia32-msvc@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz#16ca6bdadc9e054818b9c51f8dac82f6b8afab81"
|
||||
integrity sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.34.8":
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz#4cdb2cfae69cdb7b1a3cc58778e820408075e928"
|
||||
integrity sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==
|
||||
"@rollup/rollup-win32-x64-msvc@4.34.6":
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz#f3d03ce2d82723eb089188ea1494a719b09e1561"
|
||||
integrity sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==
|
||||
|
||||
"@shikijs/core@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-2.5.0.tgz#e14d33961dfa3141393d4a76fc8923d0d1c4b62f"
|
||||
integrity sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==
|
||||
dependencies:
|
||||
"@shikijs/engine-javascript" "2.5.0"
|
||||
"@shikijs/engine-oniguruma" "2.5.0"
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/vscode-textmate" "^10.0.2"
|
||||
"@types/hast" "^3.0.4"
|
||||
hast-util-to-html "^9.0.4"
|
||||
|
||||
"@shikijs/core@^2.1.0":
|
||||
"@shikijs/core@2.3.2", "@shikijs/core@^2.1.0":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-2.3.2.tgz#dcdc851e6963fe4196e2f1051302dcecce1a8706"
|
||||
integrity sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A==
|
||||
@@ -453,15 +441,6 @@
|
||||
"@shikijs/vscode-textmate" "^10.0.1"
|
||||
oniguruma-to-es "^3.1.0"
|
||||
|
||||
"@shikijs/engine-javascript@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz#e045c6ecfbda6c99137547b0a482e0b87f1053fc"
|
||||
integrity sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==
|
||||
dependencies:
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/vscode-textmate" "^10.0.2"
|
||||
oniguruma-to-es "^3.1.0"
|
||||
|
||||
"@shikijs/engine-oniguruma@2.3.2":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-2.3.2.tgz#42e64b7bbbaec5e903b12718dde1f1e1738a9c66"
|
||||
@@ -470,35 +449,27 @@
|
||||
"@shikijs/types" "2.3.2"
|
||||
"@shikijs/vscode-textmate" "^10.0.1"
|
||||
|
||||
"@shikijs/engine-oniguruma@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz#230de5693cc1da6c9d59c7ad83593c2027274817"
|
||||
integrity sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==
|
||||
"@shikijs/langs@2.3.2":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-2.3.2.tgz#a716ac528dea9e927d7088102a132c153f8a161b"
|
||||
integrity sha512-UqI6bSxFzhexIJficZLKeB1L2Sc3xoNiAV0yHpfbg5meck93du+EKQtsGbBv66Ki53XZPhnR/kYkOr85elIuFw==
|
||||
dependencies:
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/vscode-textmate" "^10.0.2"
|
||||
"@shikijs/types" "2.3.2"
|
||||
|
||||
"@shikijs/langs@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-2.5.0.tgz#97ab50c495922cc1ca06e192985b28dc73de5d50"
|
||||
integrity sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==
|
||||
"@shikijs/themes@2.3.2":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-2.3.2.tgz#c117d826ce22899dea802499a7ad5a99c2de0446"
|
||||
integrity sha512-QAh7D/hhfYKHibkG2tti8vxNt3ekAH5EqkXJeJbTh7FGvTCWEI7BHqNCtMdjFvZ0vav5nvUgdvA7/HI7pfsB4w==
|
||||
dependencies:
|
||||
"@shikijs/types" "2.5.0"
|
||||
|
||||
"@shikijs/themes@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-2.5.0.tgz#8c6aecf73f5455681c8bec15797cf678162896cb"
|
||||
integrity sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==
|
||||
dependencies:
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/types" "2.3.2"
|
||||
|
||||
"@shikijs/transformers@^2.1.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-2.5.0.tgz#190c84786ff06c417580ab79177338a947168c55"
|
||||
integrity sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-2.3.2.tgz#a62183c40cb004851312428d8681962ed487b37e"
|
||||
integrity sha512-2HDnJumw8A/9GecRpTgvfqSbPjEbJ4DPWq5J++OVP1gNMLvbV0MqFsP4canqRNM1LqB7VmWY45Stipb0ZIJ+0A==
|
||||
dependencies:
|
||||
"@shikijs/core" "2.5.0"
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/core" "2.3.2"
|
||||
"@shikijs/types" "2.3.2"
|
||||
|
||||
"@shikijs/types@2.3.2", "@shikijs/types@^2.1.0":
|
||||
version "2.3.2"
|
||||
@@ -508,18 +479,10 @@
|
||||
"@shikijs/vscode-textmate" "^10.0.1"
|
||||
"@types/hast" "^3.0.4"
|
||||
|
||||
"@shikijs/types@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-2.5.0.tgz#e949c7384802703a48b9d6425dd41673c164df69"
|
||||
integrity sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==
|
||||
dependencies:
|
||||
"@shikijs/vscode-textmate" "^10.0.2"
|
||||
"@types/hast" "^3.0.4"
|
||||
|
||||
"@shikijs/vscode-textmate@^10.0.1", "@shikijs/vscode-textmate@^10.0.2":
|
||||
version "10.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224"
|
||||
integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==
|
||||
"@shikijs/vscode-textmate@^10.0.1":
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.1.tgz#d06d45b67ac5e9b0088e3f67ebd3f25c6c3d711a"
|
||||
integrity sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==
|
||||
|
||||
"@types/estree@1.0.6":
|
||||
version "1.0.6"
|
||||
@@ -621,18 +584,18 @@
|
||||
"@vue/shared" "3.5.13"
|
||||
|
||||
"@vue/devtools-api@^7.7.0":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.7.2.tgz#49837eae6f61fc43a09f5d6c2d3210f9f73a0d09"
|
||||
integrity sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.7.1.tgz#6a44bf03ce27ba0230461171812d9ae98aeb2458"
|
||||
integrity sha512-Cexc8GimowoDkJ6eNelOPdYIzsu2mgNyp0scOQ3tiaYSb9iok6LOESSsJvHaI+ib3joRfqRJNLkHFjhNuWA5dg==
|
||||
dependencies:
|
||||
"@vue/devtools-kit" "^7.7.2"
|
||||
"@vue/devtools-kit" "^7.7.1"
|
||||
|
||||
"@vue/devtools-kit@^7.7.2":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz#3315bd5b144f98c7b84c2f44270b445644ec8f10"
|
||||
integrity sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==
|
||||
"@vue/devtools-kit@^7.7.1":
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.7.1.tgz#9b4cdef7111ffd8673c14e9a16a433c65ebb8a8e"
|
||||
integrity sha512-yhZ4NPnK/tmxGtLNQxmll90jIIXdb2jAhPF76anvn5M/UkZCiLJy28bYgPIACKZ7FCosyKoaope89/RsFJll1w==
|
||||
dependencies:
|
||||
"@vue/devtools-shared" "^7.7.2"
|
||||
"@vue/devtools-shared" "^7.7.1"
|
||||
birpc "^0.2.19"
|
||||
hookable "^5.5.3"
|
||||
mitt "^3.0.1"
|
||||
@@ -640,10 +603,10 @@
|
||||
speakingurl "^14.0.1"
|
||||
superjson "^2.2.1"
|
||||
|
||||
"@vue/devtools-shared@^7.7.2":
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz#b11b143820130a32d8ce5737e264d06ab6d62f40"
|
||||
integrity sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==
|
||||
"@vue/devtools-shared@^7.7.1":
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.7.1.tgz#3a92d7cc268c15fa639797c45b0aff79eae9b8d7"
|
||||
integrity sha512-BtgF7kHq4BHG23Lezc/3W2UhK2ga7a8ohAIAGJMBr4BkxUFzhqntQtCiuL1ijo2ztWnmusymkirgqUrXoQKumA==
|
||||
dependencies:
|
||||
rfdc "^1.4.1"
|
||||
|
||||
@@ -685,17 +648,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f"
|
||||
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
|
||||
|
||||
"@vueuse/core@12.7.0":
|
||||
version "12.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-12.7.0.tgz#b9c3880e9c01d9db86029c6a58412f1b1922497e"
|
||||
integrity sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==
|
||||
dependencies:
|
||||
"@types/web-bluetooth" "^0.0.20"
|
||||
"@vueuse/metadata" "12.7.0"
|
||||
"@vueuse/shared" "12.7.0"
|
||||
vue "^3.5.13"
|
||||
|
||||
"@vueuse/core@^12.4.0":
|
||||
"@vueuse/core@12.5.0", "@vueuse/core@^12.4.0":
|
||||
version "12.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-12.5.0.tgz#1321c75132c4f20f223e6313587ebeeec79957f2"
|
||||
integrity sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg==
|
||||
@@ -706,12 +659,12 @@
|
||||
vue "^3.5.13"
|
||||
|
||||
"@vueuse/integrations@^12.4.0":
|
||||
version "12.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-12.7.0.tgz#d9ba676a6643def3f8dcc99580162fbaf33de05e"
|
||||
integrity sha512-IEq7K4bCl7mn3uKJaWtNXnd1CAPaHLUMuyj5K1/k/pVcItt0VONZW8xiGxdIovJcQjkzOHjImhX5t6gija+0/g==
|
||||
version "12.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-12.5.0.tgz#6496ea24772d087c8fec3973a471a6ab50f9e7c0"
|
||||
integrity sha512-HYLt8M6mjUfcoUOzyBcX2RjpfapIwHPBmQJtTmXOQW845Y/Osu9VuTJ5kPvnmWJ6IUa05WpblfOwZ+P0G4iZsQ==
|
||||
dependencies:
|
||||
"@vueuse/core" "12.7.0"
|
||||
"@vueuse/shared" "12.7.0"
|
||||
"@vueuse/core" "12.5.0"
|
||||
"@vueuse/shared" "12.5.0"
|
||||
vue "^3.5.13"
|
||||
|
||||
"@vueuse/metadata@12.5.0":
|
||||
@@ -719,11 +672,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-12.5.0.tgz#8f1778a2894bdda2bf458054377a379d40276306"
|
||||
integrity sha512-Ui7Lo2a7AxrMAXRF+fAp9QsXuwTeeZ8fIB9wsLHqzq9MQk+2gMYE2IGJW48VMJ8ecvCB3z3GsGLKLbSasQ5Qlg==
|
||||
|
||||
"@vueuse/metadata@12.7.0":
|
||||
version "12.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-12.7.0.tgz#17a263927204962ec045095c83f62c81db085a46"
|
||||
integrity sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==
|
||||
|
||||
"@vueuse/shared@12.5.0":
|
||||
version "12.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-12.5.0.tgz#b93af7ab0fd6a8d879808c9bf37d540dac01da13"
|
||||
@@ -731,31 +679,24 @@
|
||||
dependencies:
|
||||
vue "^3.5.13"
|
||||
|
||||
"@vueuse/shared@12.7.0":
|
||||
version "12.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-12.7.0.tgz#0c573789069818a2e25ddae3ab64b536c614537b"
|
||||
integrity sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==
|
||||
dependencies:
|
||||
vue "^3.5.13"
|
||||
|
||||
algoliasearch@^5.14.2:
|
||||
version "5.20.3"
|
||||
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.20.3.tgz#32d79b9ffaf5a085943fab304698f46c5a3faed9"
|
||||
integrity sha512-iNC6BGvipaalFfDfDnXUje8GUlW5asj0cTMsZJwO/0rhsyLx1L7GZFAY8wW+eQ6AM4Yge2p5GSE5hrBlfSD90Q==
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.20.2.tgz#e1df37b02a4cf0f7031ff729ee9b35a7b43eeea6"
|
||||
integrity sha512-8evxG++iWyWnhng3g5RP+kwn6j+2vKLfew8pVoekn87FcfsDm92zJXKwSrU6pl+m5eAbGFhFF/gCYEQiRdbPlA==
|
||||
dependencies:
|
||||
"@algolia/client-abtesting" "5.20.3"
|
||||
"@algolia/client-analytics" "5.20.3"
|
||||
"@algolia/client-common" "5.20.3"
|
||||
"@algolia/client-insights" "5.20.3"
|
||||
"@algolia/client-personalization" "5.20.3"
|
||||
"@algolia/client-query-suggestions" "5.20.3"
|
||||
"@algolia/client-search" "5.20.3"
|
||||
"@algolia/ingestion" "1.20.3"
|
||||
"@algolia/monitoring" "1.20.3"
|
||||
"@algolia/recommend" "5.20.3"
|
||||
"@algolia/requester-browser-xhr" "5.20.3"
|
||||
"@algolia/requester-fetch" "5.20.3"
|
||||
"@algolia/requester-node-http" "5.20.3"
|
||||
"@algolia/client-abtesting" "5.20.2"
|
||||
"@algolia/client-analytics" "5.20.2"
|
||||
"@algolia/client-common" "5.20.2"
|
||||
"@algolia/client-insights" "5.20.2"
|
||||
"@algolia/client-personalization" "5.20.2"
|
||||
"@algolia/client-query-suggestions" "5.20.2"
|
||||
"@algolia/client-search" "5.20.2"
|
||||
"@algolia/ingestion" "1.20.2"
|
||||
"@algolia/monitoring" "1.20.2"
|
||||
"@algolia/recommend" "5.20.2"
|
||||
"@algolia/requester-browser-xhr" "5.20.2"
|
||||
"@algolia/requester-fetch" "5.20.2"
|
||||
"@algolia/requester-node-http" "5.20.2"
|
||||
|
||||
birpc@^0.2.19:
|
||||
version "0.2.19"
|
||||
@@ -863,9 +804,9 @@ fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
hast-util-to-html@^9.0.4:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz#ccc673a55bb8e85775b08ac28380f72d47167005"
|
||||
integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==
|
||||
version "9.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.4.tgz#d689c118c875aab1def692c58603e34335a0f5c5"
|
||||
integrity sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==
|
||||
dependencies:
|
||||
"@types/hast" "^3.0.0"
|
||||
"@types/unist" "^3.0.0"
|
||||
@@ -874,7 +815,7 @@ hast-util-to-html@^9.0.4:
|
||||
hast-util-whitespace "^3.0.0"
|
||||
html-void-elements "^3.0.0"
|
||||
mdast-util-to-hast "^13.0.0"
|
||||
property-information "^7.0.0"
|
||||
property-information "^6.0.0"
|
||||
space-separated-tokens "^2.0.0"
|
||||
stringify-entities "^4.0.0"
|
||||
zwitch "^2.0.4"
|
||||
@@ -961,9 +902,9 @@ micromark-util-types@^2.0.0:
|
||||
integrity sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==
|
||||
|
||||
minisearch@^7.1.1:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-7.1.2.tgz#296ee8d1906cc378f7e57a3a71f07e5205a75df5"
|
||||
integrity sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-7.1.1.tgz#901d0367f078233cdc7a10be7264e09c6248cf5f"
|
||||
integrity sha512-b3YZEYCEH4EdCAtYP7OlDyx7FdPwNzuNwLQ34SfJpM9dlbBZzeXndGavTrC+VCiRWomL21SWfMc6SCKO/U2ZNw==
|
||||
|
||||
mitt@^3.0.1:
|
||||
version "3.0.1"
|
||||
@@ -976,9 +917,9 @@ nanoid@^3.3.8:
|
||||
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
|
||||
|
||||
oniguruma-to-es@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz#480e4bac4d3bc9439ac0d2124f0725e7a0d76d17"
|
||||
integrity sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-3.1.0.tgz#6e74d9ef4e8e33a61ad28c1f564b7d0ce1d0b0d9"
|
||||
integrity sha512-BJ3Jy22YlgejHSO7Fvmz1kKazlaPmRSUH+4adTDUS/dKQ4wLxI+gALZ8updbaux7/m7fIlpgOZ5fp/Inq5jUAw==
|
||||
dependencies:
|
||||
emoji-regex-xs "^1.0.0"
|
||||
regex "^6.0.1"
|
||||
@@ -995,23 +936,23 @@ picocolors@^1.1.1:
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
postcss@^8.4.43, postcss@^8.4.48:
|
||||
version "8.5.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.3.tgz#1463b6f1c7fb16fe258736cba29a2de35237eafb"
|
||||
integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
|
||||
version "8.5.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.2.tgz#e7b99cb9d2ec3e8dd424002e7c16517cb2b846bd"
|
||||
integrity sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==
|
||||
dependencies:
|
||||
nanoid "^3.3.8"
|
||||
picocolors "^1.1.1"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
preact@^10.0.0:
|
||||
version "10.26.2"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.26.2.tgz#d737055584a4d8004ec273e425fb4c30960aa512"
|
||||
integrity sha512-0gNmv4qpS9HaN3+40CLBAnKe0ZfyE4ZWo5xKlC1rVrr0ckkEvJvAQqKaHANdFKsGstoxrY4AItZ7kZSGVoVjgg==
|
||||
version "10.25.4"
|
||||
resolved "https://registry.yarnpkg.com/preact/-/preact-10.25.4.tgz#c1d00bee9d7b9dcd06a2311d9951973b506ae8ac"
|
||||
integrity sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==
|
||||
|
||||
property-information@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.0.0.tgz#3508a6d6b0b8eb3ca6eb2c6623b164d2ed2ab112"
|
||||
integrity sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==
|
||||
property-information@^6.0.0:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec"
|
||||
integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==
|
||||
|
||||
regex-recursion@^6.0.2:
|
||||
version "6.0.2"
|
||||
@@ -1038,45 +979,45 @@ rfdc@^1.4.1:
|
||||
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
|
||||
|
||||
rollup@^4.20.0:
|
||||
version "4.34.8"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.8.tgz#e859c1a51d899aba9bcf451d4eed1d11fb8e2a6e"
|
||||
integrity sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==
|
||||
version "4.34.6"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.6.tgz#a07e4d2621759e29034d909655e7a32eee9195c9"
|
||||
integrity sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.6"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.34.8"
|
||||
"@rollup/rollup-android-arm64" "4.34.8"
|
||||
"@rollup/rollup-darwin-arm64" "4.34.8"
|
||||
"@rollup/rollup-darwin-x64" "4.34.8"
|
||||
"@rollup/rollup-freebsd-arm64" "4.34.8"
|
||||
"@rollup/rollup-freebsd-x64" "4.34.8"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.34.8"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.34.8"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.34.8"
|
||||
"@rollup/rollup-linux-loongarch64-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.34.8"
|
||||
"@rollup/rollup-linux-x64-musl" "4.34.8"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.34.8"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.34.8"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.34.8"
|
||||
"@rollup/rollup-android-arm-eabi" "4.34.6"
|
||||
"@rollup/rollup-android-arm64" "4.34.6"
|
||||
"@rollup/rollup-darwin-arm64" "4.34.6"
|
||||
"@rollup/rollup-darwin-x64" "4.34.6"
|
||||
"@rollup/rollup-freebsd-arm64" "4.34.6"
|
||||
"@rollup/rollup-freebsd-x64" "4.34.6"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.34.6"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.34.6"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.34.6"
|
||||
"@rollup/rollup-linux-loongarch64-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.34.6"
|
||||
"@rollup/rollup-linux-x64-musl" "4.34.6"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.34.6"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.34.6"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.34.6"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
shiki@^2.1.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-2.5.0.tgz#09d01ebf3b0b06580431ce3ddc023320442cf223"
|
||||
integrity sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-2.3.2.tgz#d13bae8403c8aec11907185b4d96746b317cf539"
|
||||
integrity sha512-UZhz/gsUz7DHFbQBOJP7eXqvKyYvMGramxQiSDc83M/7OkWm6OdVHAReEc3vMLh6L6TRhgL9dvhXz9XDkCDaaw==
|
||||
dependencies:
|
||||
"@shikijs/core" "2.5.0"
|
||||
"@shikijs/engine-javascript" "2.5.0"
|
||||
"@shikijs/engine-oniguruma" "2.5.0"
|
||||
"@shikijs/langs" "2.5.0"
|
||||
"@shikijs/themes" "2.5.0"
|
||||
"@shikijs/types" "2.5.0"
|
||||
"@shikijs/vscode-textmate" "^10.0.2"
|
||||
"@shikijs/core" "2.3.2"
|
||||
"@shikijs/engine-javascript" "2.3.2"
|
||||
"@shikijs/engine-oniguruma" "2.3.2"
|
||||
"@shikijs/langs" "2.3.2"
|
||||
"@shikijs/themes" "2.3.2"
|
||||
"@shikijs/types" "2.3.2"
|
||||
"@shikijs/vscode-textmate" "^10.0.1"
|
||||
"@types/hast" "^3.0.4"
|
||||
|
||||
source-map-js@^1.2.0, source-map-js@^1.2.1:
|
||||
|
||||
Reference in New Issue
Block a user