Como aplicar um patch no kernel?

Não, não, Luke !
É EFAULT mesmo.

É um dos erros padrões. Tem alguns nesse link.

https://www.kernel.org/doc/html/v4.18/media/uapi/gen-errors.html

2 curtidas

Você sabe aplicar patch no kernel Linux?

Eu ?

É algo que nunca fiz.

Vou testar, aqui.
É Arch, né ?
Pois então vou dar uma lida e testar.

Se vai testar em VM, uma seria ir de CalamArch, mais rápido pra instalar (mesmo demorado, é muito menos que “na unha”)

1 curtida

Provavelmente o patch dele deve ser aplicado tipo aqueles patch que tem no kernel.org de uma versão para outra.
Eu também nunca apliquei.
Eu sempre baixei o tar.xz inteiro.

Excelente este link, matou várias curiosidades minha, vlw chimpa! :pray:t2:

1 curtida

Eu vou fazer o procedimento depois, quando eu tiver no PC. Mas já vou colocando umas dúvidas aqui pra adiantar.

Supondo que eu tenha feito o seguinte:

  1. Baixei o tarball do kernel.
  2. Baixei o arquivo kernel.patch que eu citei acima.
  3. Extraí o código fonte do kernel baixado para a pasta que eu vou compilar.

Lendo o arquivo do patch lá eu vi que parece que ele vai alterar um arquivo chamado devio.c
que está no diretório linux-x.x/drivers/usb/core/devio.c
.
Tem alguma coisa nesse arquivo patch que eu tenho que alterar? Por exemplo, eu vi que lá no começo tem isso:

diff -ur /home/xyz/Downloads/linux-4.14.83/drivers/usb/core/devio.c ./drivers/usb/core/devio.c
--- /home/xyz/Downloads/linux-4.14.83/drivers/usb/core/devio.c 2018-11-23 02:19:27.000000000 -0500
+++ ./drivers/usb/core/devio.c 2019-09-15 13:15:53.973022982 -0400

Eu acho que tenho que alterar esse /home/xyz/... para o diretório onde está o kernel descompactado, e alterar esse linux-4.14.83 para a versão do que eu baixei. É isso mesmo?

E supondo que eu esteja já na pasta do kernel extraído, como eu uso o comando patch para aplicar esse patch?

Desculpem minha noobice, é que eu nunca fiz isso aí antes. Já compilei o kernel uma vez, no Ubuntu, mas nunca fiz esse negócio de patchear. Também vou ler mais depois sobre compilação de kernel e a documentação do comando patch.

No Arch Linux é extrememente simples vc compilar o kernel.

1º Crie um diretório em sua home chamado build e entre no diretório build

$ mkdir ~/build
$ cd ~/build

2º Instale no seu arch o pacote “asp” “base-devel” “pacman-contrib”

$ sudo pacman -S asp base-devel pacman-contrib --needed

3º Utilize o asp para fazer download do kernel, exemplo abaixo usa o kernel lts
Atualiza a lista de pacotes

$ asp update linux-lts

Exporta o pacote

$ asp export linux-lts

4º Entre no diretório linux-lts, copie o patch para o diretório linux-lts e adicione o patch no PKGBUILD conforme o exemplo.

$ cd ~/build/linux-lts
$ cp seu_patch ~/build/linux-lts/
$ vim ~/build/linux-lts/PKGBUILD

  • No PKGBUILD mude:

pkgbase=linux-lts

para

pkgbase=linux-custom-lts

  • Ainda no PKGBUILD caso deseje editar as config do kernel comente:

#make olddefconfig

adicione

make nconfig

5º Após fazer as modificações no PKGBUILD, gere um novo checksum com comando abaixo.
OBS: Toda vez que fizer alguma alteração ou adição de arquivos gere novamente com comando abaixo.

$ updpkgsums

6º Hora de compilar:

$ makepkg -s

7º Após o processo terminar será gerado os arquivos
linux-custom-lts-5.8.12-x86_64.pkg.tar.zst
linux-custom-lts-headers-5.8.12-x86_64.pkg.tar.zst

Agora basta instalar com

$ sudo pacman -U linux-custom-lts-5.8.12-x86_64.pkg.tar.zst linux-custom-lts-headers-5.8.12-x86_64.pkg.tar.zst

8º Caso não seja feito automaticamente recrie o ramdisk

$ sudo mkinitcpio -P

9º Provavelmente irá precisar recriar o arquivo do grub

$ sudo grub-mkconfig -o /boot/grub/grub.cfg

10º Reinicie o pc e selecione o kernel instalado, esse é um guia básico, mas configurações pode ser encontradas na wiki do arch.

9º Caso deseje desinstalar o kernel compilado, execute o comando abaixo e repita o passo 8, 9 e 10

$ sudo pacman -Rsn linux-custom-lts linux-custom-lts-headers

2 curtidas

Pois então.

O “grosso” da operação é compilar o kernel, mesmo.

Nesse caso aí, esse path é pro usb. Altera o arquivo drivers/usb/core/devio.c

Como era pro kernel 4.14 e eu baixei o 5.10, as linhas afetadas não eram mais as mesmas.

Então, eu fiz uma cópia do cara e alterei as linhas correspondentes na cópia.

Depois rodei o diff. Aí foi só executar o comando patch. Não tem segredo.

Depos disso, é todo aquele processo de compilar o kernel, etc, etc.

Mas vou logo avisando que esse cara aí é meio “mandrake”.

É que, se você olhar bem, o original faz um “check_alguma_coisa” e decide o que fazer em seguida, baseado no return code.

Esse “path” aí, consiste em ignorar o return code e prosseguir normalmente em qualquer situação. Acho que o autor fez um “hack”, e não um “path”.

A primeira linha você pode até deletar.

a linha que começa com “—” tem que refletir a localização do arquivo do kernel, a partir da pasta que você está.

A linha que começa com “+++” pode ter qualquer coisa.

Aí é que a coisa pega.

As linhas que começam com “@” informam o número da linha que o suposto código está no arquivo original do kernel. Mas como provavelmente não é a mesma versão que você está usando, vai dar xabu, uma vez que o arquivo está bem diferente.

O mais eficiente seria.

  • copie o arquivo do kernel para algum lugar.
  • localize o código que ele referencia. No caso, eu mandei localizar “check_ctrlrecip”. O primeiro “match” foi na própria rotina. O segundo foi aí onde ele alterou.
  • Altere a cópia. No caso, ele simplesmente adiciona a linha “ret = 0;”
  • Repetindo a busca por “check_ctrlrecip” você cai no segundo lugar que ele alterou. Ele fez a mesma coisa. Inseriu a linha “ret = 0;”
  • Finalmente, localize “USBDEVFS”. Vai dar nesse case que ele alterou. E foi a mesma alteração, inserindo a linha “ret = 0;”

Feitas as alterações, você mesmo gera o arquivo diff, com o comando

diff -ur caminho_para_o_arquivo_original caminho_para_o_arquivo_alterado > teste.patch

No começo do arquivo .patch tem o caminho esperado do arquivo que será alterado. Nesse caso é esperado que vc esteja na raiz de onde extraiu o kernel. Daí é mandar aplicar executar o comando informando o arquivo .patch.

Por exemplo, vc extraiu o código fonte em /home/thiago/Downloads/linux-5.10.9
Vc tem o arquivo .patch em /home/thiago/Downloads

cd /home/thiago/Downloads/linux-5.10.9
patch -p1 < /home/thiago/Downloads/kernel.patch

Deve aparecer na tela um resumo das alterações feitas. Daí já tá pronto. Em alguns casos o programa pode não conseguir resolver conflitos, daí precisa de conhecimentos de programador pra resolver isso, mas espero que não seja necessário. Outra opção seria vc fazer do download e compilar a mesma versão de kernel indicada pelo patch, que daí é certeza que vai funcionar automaticamente.

Eu sei como fazer a compilação manual, mas o camarada Daniel indicou aí um caminho específico para o Arch, que é preferível. Nesse caso vc pode usar a opção dele de rodar o patch automaticamente, mas eu preferiria aplicar o patch manualmente pra ver se não dá erros, garantindo assim que a compilação vai gerar um kernel com a alteração que vc quer.

3 curtidas

Volto a alertar que existe o problema do devio.c não ser mais o que era no kernel para o qual o cara fez o patch.

1 curtida

Entendo. O código do “patch” é realmente tenebroso, setar o código de retorno sempre como OK seria np máximo uma tentativa de debug “living la vida loka”. Mas o colega está realmente disposto a fazer o procedimento para salvar o celular dele.

Não é só isso, Rui.

A linha em que o arquivo de patch diz que está a primeira parte do código a ser alterado é a 1090. No kernel 5.10.12, essa linha é a 1113.

@Thiago12 O kernel 4.14 esta disponível para download no kernel.org e tera suporte por um bom tempo.
Baixa ele e aplica o patch.
@chimpa_theist Não tem modificação de linha só tem adicionamento de linha.
Provavelmente as linhas adicionada nesse patch são independente.

O programa patch resolve esse problema do número da linha. Ele compara as linhas acima e abaixo pra tentar achar o local exato da alteração e realizar. É a parte automática que resolve bem muitos conflitos. Ele só vai ter problemas se houver mais alterações onde ele assume que não houve. Daí deve haver intervenção manual.

Só que provavelmente não vai achar.

Não tem mais aquele

	return -EFAULT;

antes do

ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest,
		      ctrl.wIndex);

No 5.10.12

1 curtida

Então ou edita o arquivo, ou faz a compilação com o kernel 4.4 e reza pra ter os drivers do hardware dele naquela versão de kernel! Eu já estou começando a achar que é mais simples instalar o windows pra usar as ferramentas que o pessoal indica nos foruns.

3 curtidas

Pô. Vou desdizer o que disse.

Acabei de testar aqui e ele deu um jeito, assim mesmo. O resultado foi

patching file ./drivers/usb/core/devio.c
Hunk #1 succeeded at 1113 with fuzz 1 (offset 23 lines).
Hunk #2 succeeded at 1573  (offset 63 lines).
Hunk #3 succeeded at 2638  (offset 104 lines).

Ou seja, mesmo a linha não existindo mais, ele se virou com esse fuzz 1 aí.

Tô de queixo caído !

1 curtida

É igual eu expliquei o patch deve ter sido escrito para ser independente.
@Deleterium O suporte da AMD já esta no Linux a mais de 5 anos e o suporte do kernel LTS vai por 5 anos.
O meu kernel 4.4 tem driver da AMD.
Kernel antigo não tem driver de chips AMD recente.