Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -*- Introdução -*-
- Nesse procedimento vou documentar o que eu fiz para
- criar um initrd customizado. Os unicos motivos para você precisar de
- um initrd - que eu conheço - são: - Quando deseja bootar por LABEL ou
- UUID (meu caso) - Quando o /usr fica em uma partição diferente da do /
- - Quando o driver de disco onde sua partição / fica foi compilado como
- modulo.
- Fora esses casos - e algum outro que eu disconheça - você não precisa de um initrd.
- Nesse procedimento eu vou criar o initrd, na "UNHA", é possivel - e
- mais indicado - usar ferramentas para o mesmo. Das que eu ja usei o
- Dracut [1] foi o que mais me agradou.
- Um initrd, initramdisk ou initramfs é uma estrurura de diretorios
- epacotada com cpio e compressa com gzip. Essa estrutura é como se
- fosse um mini-sistema. Durante o processo de boot o kernel "explode"
- esse arquivo e executa o script /init. O /init tem como principal
- resposabilidade montar o / real e fazer um chroot para o mesmo. Para
- montar o root podem haver dependencias, por exemplo no meu caso, eu
- quero confiar somente no LABEL e não num path /dev/sdX, por isso
- preciso executar um comando para achar o meu fs baseando-me no LABEL
- antes de montar o /.
- Estou criando esse guia porque perdi cerca de 3 horas por causa de
- detalhes. E da proxima vez não quero perder meu tempo tentando
- desvenda-los de novo. E aproveito para passar o conhecimento para
- frente..
- -*- Dependencias -*-
- Para executar esse procedimento você precisa ter instalado os binarios
- abaixo:
- gzip
- cpio
- findfs (para bootar por LABEL)
- busybox
- -*- Procedimento -*-
- NOTA: Todos os procedimentos aqui foram executados como root.
- 1. Crie um diretorio que vai hospedar toda a estrutura do ram disk.
- # mkdir initramfs
- 2. Crie a estrutura de diretorios
- # cd initramfs
- # mkdir -p bin lib dev etc mnt/root proc root sbin sys
- 3. Copie e instale o busybox
- # cd bin
- # cp -aL /usr/bin/busybox .
- # busybox --install .
- Isso vai criar uma serie de arquivos com os nomes dos binarios mais
- usados. Verifique que foram instalados com sucesso
- # ls -l
- 4. Populando o initrd
- A grande maioria dos binarios depende de alguma(s) bibliotecas, com o
- busybox não é diferente. O comando ldd serve para exibir essas
- dependencias.
- # cd
- # ldd initramfs/bin/busybox
- linux-gate.so.1 => (0xb77e6000)
- libpam_misc.so.0 => /lib/libpam_misc.so.0 (0xb77a5000)
- libc.so.6 => /lib/libc.so.6 (0xb7656000)
- libpam.so.0 => /lib/libpam.so.0 (0xb7649000)
- /lib/ld-linux.so.2 (0xb77ca000)
- libdl.so.2 => /lib/libdl.so.2 (0xb7645000)
- Precisamos copiar cada lib para o diretorio lib do nosso initramfs o
- unico que não é necessario é o linux-gate.so.1.
- # cd initramfs/lib
- # cp -aL /lib/libpam_misc.so.0 .
- # cp -aL /lib/libc.so.6 .
- # cp -aL /lib/libpam.so.0 .
- # cp -aL /lib/ld-linux.so.2 .
- # cp -aL /lib/libdl.so.2 .
- Para verificar que tudo está OK, configure o LD_LIBRARY_PATH para o
- diretorio lib e execute o ldd novamente. O ld-linux é o unico que vai
- aparecer sob /lib. E o linux-gate pode ser ignorado.
- # export LD_LIBRARY_PATH=/root/initramfs/lib
- # ldd /root/initramfs/bin/busybox
- linux-gate.so.1 => (0xb772f000)
- libpam_misc.so.0 => /root/initramfs/lib/libpam_misc.so.0 (0xb770e000)
- libc.so.6 => /root/initramfs/lib/libc.so.6 (0xb75bf000)
- libpam.so.0 => /root/initramfs/lib/libpam.so.0 (0xb75b2000)
- /lib/ld-linux.so.2 (0xb7713000)
- libdl.so.2 => /root/initramfs/lib/libdl.so.2 (0xb75ae000)
- # unset LD_LIBRARY_PATH
- Colocarei tambem o findfs, responsavel por encontrar a partição a partir de um LABEL.
- # ldd /sbin/findfs
- linux-gate.so.1 => (0xb7789000)
- libblkid.so.1 => /lib/libblkid.so.1 (0xb7728000)
- libc.so.6 => /lib/libc.so.6 (0xb75d9000)
- libuuid.so.1 => /lib/libuuid.so.1 (0xb75d3000)
- /lib/ld-linux.so.2 (0xb776d000)
- # cp /sbin/findfs /root/initramfs/sbin/.
- # cd /root/initramfs/lib
- # cp -aL /lib/libblkid.so.1 .
- # cp -aL /lib/libc.so.6 .
- # cp -aL /lib/libuuid.so.1 .
- # cp -aL /lib/ld-linux.so.2 .
- Caso você deseje colocar algum outro binario no initrd precisa
- executar o mesmo procedimento apontado acima. Alem das libs, alguns
- binarios dependem de outros arquivos, como arquivos de configuração
- etc. Não se esqueça que muitos binarios dependem de pacotes. Por
- exemplo o vim depende do ncurses. Para descobrir os arquivos que um
- binario tenta abrir durante seu startup - usarei o vim no exemplo -
- execute o comando abaixo.
- # LC_ALL=C
- # strace -o vim-open-syscalls -e vim
- Lembre-se de executar o comando abaixo em um tty, assim você está mais
- proximo do que vai encontrar durante o boot. O arquivo
- vim-open-syscalls vai conter todas as chamadas a open do vim, contento
- os arquivos usados como parametros. Você precisa usar seu bom senso
- aqui, nem tudo é extritamente necessario para o vim funcionar.
- Para validar que o initrd esta OK, execute o comando abaixo.
- # chroot /root/initramfs /bin/sh
- Se o shell abrir está tudo OK. Você deve testar os otros binarios,
- caso haja algum, também. Se você receber um "No such file or
- directory" significa que alguma lib está faltando, impedindo o binario
- de subir.
- É bom colocar os modulos do kernel no initrd, para isso execute os
- comandos abaixo.
- # cd /root/initramfs
- # tar vcO /lib/modules/$(uname -r)/kernel/drivers/ | tar vx
- 5 Crie o script init
- Segue abaixo o script init que eu estou usando. Esse script deve ficar
- na rais do initrd, no meu caso é /root/initramfs/init.
- ------------- INICIO DO init ---------------
- #!/bin/busybox sh
- rescue_shell() {
- echo "Something went wrong. Dropping you to a shell."
- exec /bin/sh
- }
- uuidlabel_root() {
- for cmd in $(cat /proc/cmdline) ; do
- case $cmd in
- root=*)
- dev=${cmd#root=}
- type=${dev%%=*}
- if [ $type = "LABEL" ] || [ $type = "UUID" ] ; then
- mount -o ro $(findfs "$dev") /mnt/root
- else
- mount -o ro ${dev} /mnt/root
- fi
- ;;
- esac
- done
- }
- # Mount the /proc and /sys filesystems.
- mount -t proc none /proc
- mount -t sysfs none /sys
- # Do your stuff here.
- echo "This script mounts rootfs and boots it up, nothing more!"
- mount -t devtmpfs none /dev
- uuidlabel_root || rescue_shell
- # Clean up.
- umount /proc
- umount /sys
- umount /dev
- # Boot the real thing.
- exec switch_root /mnt/root /sbin/init
- ------------- FIM DO init ---------------
- De permição de execução para o init
- # chmod +x /root/initramfs/init
- Durante o processo de boot, o initrd é explodido no /, o falso /,
- entao o script init é executado sob esse "mini-sistema". Ele é
- reponsavel por encontrar o / real, monta-lo e então executar um
- swich_root para o / real.
- 6 Configuração do kernel
- NOTA: Se você ja usa um initrd então seu kernel já tem suporte e você pode pular essa sessão.
- O suporte ao inird é dado pela opção CONFIG_BLK_DEV_INITRD. Execute o
- comando abaixo no arquivo config do seu kernel para saber se ele tem
- suporte ao initrd
- # grep INITRD config-SEU_KERNEL
- O config geralmente pode ser encontrado em /boot, com o nome
- config-<SEU_KERNEL>. Se não estiver no /boot, procure no
- /usr/src/linux por .config. Se mesmo assim não tiver procure por
- /proc/config.gz.. Esse arquivo é um zipado do config mantido dentro do
- /proc, provavelmente entao execute
- # zgrep INITRD /proc/config.gz
- Se você não encontrou em nenhum dos casos acima, a sua unica opção é
- compilar o kernel novamente par ter certeza de que ele suporta o
- initrd. A opção pode ser encontrada em
- General Setup ------>
- Initial RAM filesystem and RAM disk ..
- Aproveite e abilite as opções abaixo também. Assim você tem acesso ao
- config pelo /proc/config.gz
- <*> Kernel .config support
- [*] Enable access to .config through /proc/config.gz
- 7. Empacotando o initrd.
- Execute o comando abaixo para empacotar o initrd, ja no diretorio
- /boot, coloque o nome que prefirir, mas lembre que esse nome sera
- usado no menu.lst do grub no passo seguinte.
- # cd /root/initramfs
- # find . -print0 | cpio --null -ov --format=newc | gzip -9 > /boot/gkos-initramfs.cpio.gz
- 8. No grub
- ATENÇÃO: Não edite o bloco do grub que ja funciona! Em vez disso copie
- e cole e edite a copia. Do contrario você pode acabar com uma unica
- opção - que não funcina - na hora do boot.
- Crie um novo bloco - no arquivo /boot/grub/menu.lst - contendo o
- initrd. Veja como ficou o meu:
- # gentoo 3.3.8 with initrd
- title gentoo-3.3.8 initrd
- root (hd0,0)
- kernel /boot/gentoo-3.3.8 root=LABEL=gentoo-Root ro
- initrd /boot/gkos-initramfs.cpio.gz
- 9. Reboot
- Salve tudo, faça o double check padrão e reboot a maquina. Selecione a
- nova opção no grub e cruse os dedos.
- -*- Referencias -*-
- http://en.gentoo-wiki.com/wiki/Initramfs
- [1] https://dracut.wiki.kernel.org/index.php/Main_Page
Advertisement
Add Comment
Please, Sign In to add comment