Como compilar arquivos extras no diretório raiz de uma ROM do Android

8

Estou construindo um kernel Android personalizado baseado no código-fonte do kernel da Cyanogenmod ROM. Gostaria de adicionar pastas e arquivos à pasta raiz do sistema operacional ( /). Por exemplo, depois de compilar meu kernel, eu gostaria que uma pasta extra chamada toto(caminho absoluto = /toto) fosse criada.

Eu realmente não tenho idéia de quais arquivos precisam ser editados e como fazer o trabalho.


Nota: Se você é um usuário do Android (não um desenvolvedor de ROM) e deseja adicionar arquivos ao seu rootfs, consulte a pergunta relevante do Android.SE .

deadeert
fonte
3
O Android é um sistema Linux, mas como a pergunta é específica para o Android, não para todos os Unixes. Melhor lugar para isso é em android.stackexchange.com
enedil
@enedil De um modo geral, as perguntas sobre o Android não são abordadas aqui, já que o Android não é Linux no senso comum do termo (ele apenas usa um kernel do Linux). No entanto, a mesma pergunta se aplicaria a outros sistemas Linux embarcados, então acho que está bem aqui.
Gilles 'SO- stop be evil'
@ Graeme Na verdade, o sistema de arquivos raiz é compilado em todos os kernel. Normalmente está vazio e descompactamos um arquivo cpio - nossa imagem initramfs. Você pode colocar o que quiser, no momento da compilação.
mikeserv
@enedil Neste caso, acredito que esta questão seja totalmente sobre o assunto. O Android difere mais dos outros unixes, userspace,mas de outros Linux, a in-kerneldiferença é de apenas um punhado de patches. De fato, a popularidade do Android é uma grande força motriz por trás do desenvolvimento do kernel, e existe há alguns anos. Dê uma olhada nos changelogs do kernel.org e decida por si mesmo quantos são relevantes para os sistemas móveis - o Android em particular.
mikeserv
Uma pergunta semelhante no Android.SE: Como descompactar e editar boot.imgpara portar ROM? : as respostas lá explicam como buscar e editar o boot.imgarquivo, permitindo alterar persistentemente o conteúdo do diretório raiz do dispositivo.
WhiteWinterWolf

Respostas:

7

No Android, como em muitos sistemas baseados em Linux, o kernel primeiro monta um initramfs on /. O initramfs é armazenado na RAM; ele é carregado de um arquivo CPIO que é armazenado junto com o próprio kernel (ou em algum outro local onde o gerenciador de inicialização pode encontrá-lo).

A maioria dos sistemas Linux de desktop possui um pequeno initramfs que contém apenas programas e arquivos de configuração suficientes para montar o sistema de arquivos raiz real, que é então montado /, substituindo o initramfs. O Android, como alguns sistemas Linux embarcados, mantém os initramfs montados para sempre. Initramfs do Android contém apenas /init, adbde alguns arquivos de configuração.

Para o Cyanogenmod, você pode encontrar instruções de construção no guia de portabilidade . Você deseja copiar mais arquivos para o ramdisk (a imagem initramfs, na terminologia do Android), portanto, você deve adicioná-los à PRODUCT_COPY_FILESlista no device_*.mkmakefile do seu dispositivo.

Gilles 'SO- parar de ser mau'
fonte
Na verdade, nosso arquivo de initramfs imagem é o que contém esses arquivos de configuração, o initramfs sistema de arquivos é compilado em todos os kernel.
mikeserv
1
@ mikeserv Convido você a se familiarizar com o conceito de metonímia . A redação técnica usa menos do que a fala comum, mas recebe uso ocasional.
Gilles 'SO- stop be evil'
Vou fazê-lo, mas primeiro eu tenho que verificá-la no dicionário ...
mikeserv
Você faz uma observação muito boa e, como eu disse antes, a única razão pela qual sou inflexível quanto a isso é que parece tão pouco entendido, mas é realmente muito direto, então eu tendem a falar sobre esse assunto - pelo qual peço desculpas . Apenas acho que seria mais fácil mostrar aos outros como é simples projetar seu próprio sistema a partir do kernel se os detalhes acima forem esclarecidos. Mais uma vez, desculpe, Gilles, não quero dizer nenhum insulto.
precisa saber é o seguinte
@mikeserv Obrigado por seus conselhos. Eu localizei o arquivo usado para copiar blobs (blbs.mk). Ainda não entendo quais arquivos devem ser editados para adicionar uma pasta em rootfs (/). Eu posso acessar os arquivos init * .rc da rom, mas agora não o faço se editar (adicionando um mkdir / titi, por exemplo) esses arquivos me permitirão adicionar permanentemente minhas pastas (/ titi). Depois disso, adicionarei o arquivo PRODUCT_COPY_FILES + = / titi / myfile: <localpath> / myfiles. Qualquer pista ? Obrigado novamente
deadeert
1

Os documentos do kernel explicam como compactar uma imagem no próprio kernel. Do kernel.org :

O que é rootfs?

Rootfsé uma instância especial de ramfs(ou tmpfs, se estiver ativada), que está sempre presente nos sistemas 2.6. Você não pode desmontarrootfs pelo mesmo motivo que não pode matar o processo init; em vez de ter um código especial para procurar e manipular uma lista vazia, é menor e mais simples para o kernel garantir que determinadas listas não possam ficar vazias.

A maioria dos sistemas simplesmente monta outro sistema de arquivos rootfse o ignora. A quantidade de espaço que uma instância vazia de ramfs ocupa é pequena.

Se CONFIG_TMPFS estiver ativado, rootfsserá usado em tmpfsvez de ramfspor padrão. Para forçar ramfs, adicione "rootfstype=ramfs"à linha de comando do kernel.

O que é o initramfs?

Todos os kernels 2.6 do Linux contêm um arquivo compactado em"cpio"formatogzip, que é extraído rootfsquando o kernel é inicializado. Após a extração, o kernel verifica serootfscontém um arquivoe"init" , se for o caso, executa-o como PID 1. Se encontrado, esseinitprocesso é responsável por elevar o sistema até o fim, incluindo a localização e montagem do dispositivo raiz real ( caso existam). Serootfsnão contiver uminitprograma após acpioextração do arquivoincorporado, o kernel recorrerá ao código mais antigo para localizar e montar uma partição raiz e, em seguida, executar alguma variante/sbin/initdisso.

Tudo isso difere do antigo initrd de várias maneiras:

  • O initrd antigo sempre foi um arquivo separado, enquanto o arquivo initramfs está vinculado à imagem do kernel do linux. (O diretório linux - * / usr é dedicado à geração desse arquivo durante a construção.)

  • O arquivo initrd antigo era uma imagem do sistema de arquivos compactada com gzip (em algum formato de arquivo, como ext2, que precisava de um driver embutido no kernel), enquanto o novo arquivo initramfs é um arquivo cpio compactado com gzip (como tar apenas mais simples, consulte cpio (1) e Documentação / early-userspace / buffer-format.txt). O código de extração cpio do kernel não é apenas extremamente pequeno, é também __init texto e dados que podem ser descartados durante o processo de inicialização.

  • O programa executado pelo antigo initrd (que foi chamado / initrd, não / init) fez algumas configurações e depois retornou ao kernel, enquanto o programa init do initramfs não deve retornar ao kernel. (Se o / init precisar transferir o controle, ele poderá sobrescrever / com um novo dispositivo raiz e executar outro programa init. Consulte o utilitário switch_root, abaixo.)

  • Ao alternar outro dispositivo raiz, o initrd pivot_root e desmontar o ramdisk. Mas initramfs é rootfs: você não pode pivot_root rootfs nem desmontá-lo. Em vez disso, exclua tudo do rootfs para liberar espaço (encontre -xdev / -exec rm '{}' ';'), substitua o rootfs pela nova raiz (cd / newmount; mount --move. /; Chroot.), conecte stdin / stdout / stderr ao novo / dev / console e execute o novo init.

Como esse é um processo notavelmente persnickety (e envolve a exclusão de comandos antes que você possa executá-los), o pacote klibc introduziu um programa auxiliar (utils / run_init.c) para fazer tudo isso por você. A maioria dos outros pacotes (como o busybox) nomeou esse comando "switch_root".

Preenchendo initramfs:

O processo de compilação do kernel 2.6 sempre cria um arquivo initramfs no formato cpio com gzip e o vincula ao binário resultante do kernel. Por padrão, esse arquivo está vazio (consumindo 134 bytes em x86).

A opção de configuração CONFIG_INITRAMFS_SOURCE (em Configuração geral no menuconfig,e viver em usr/Kconfig) pode ser usado para especificar uma fonte para o initramfsarquivo, que irá automaticamente ser incorporado no binário resultante. Esta opção pode apontar para um arquivo * existente compactado com gzip cpio*, um diretório que contém arquivos a serem arquivados ou uma especificação de arquivo de texto , como no exemplo a seguir:

 dir /dev 755 0 0
 nod /dev/console 644 0 0 c 5 1
 nod /dev/loop0 644 0 0 b 7 0
 dir /bin 755 1000 1000
 slink /bin/sh busybox 777 0 0
 file /bin/busybox initramfs/busybox 755 0 0
 dir /proc 755 0 0
 dir /sys 755 0 0
 dir /mnt 755 0 0
 file /init initramfs/init.sh 755 0 0

Execute " usr/gen_init_cpio" (após a compilação do kernel) para obter uma mensagem de uso documentando o formato de arquivo acima.

Uma vantagem do arquivo de configuração é que o rootacesso não é necessário para definir permissões ou criar nós do dispositivo no novo arquivo morto.

(Observe que essas duas entradas de "arquivo" de exemplo esperam encontrar arquivos denominados " init.sh" e " busybox" em um diretório chamado " initramfs", no linuxdiretório -2.6. *. Consulte Documentação / espaço de usuário antigo / README para obter mais detalhes.)

O kernel não depende de cpioferramentas externas . Se você especificar um diretório em vez de um arquivo de configuração, a infraestrutura de compilação do kernel criará um arquivo de configuração desse diretório ( usr/Makefilechamadas scripts/gen_initramfs_list.sh) e continuará a empacotar esse diretório usando o arquivo de configuração (alimentando-o para o usr/gen_init_cpioqual é criado a partir de usr/gen_init_cpio.c). O código de criação em tempo de compilação do kernel cpioé totalmente independente e o extrator de tempo de inicialização do kernel também é (obviamente) independente.

mikeserv
fonte