danielhilst

Criando um initrd na UNHA

Nov 10th, 2012
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.04 KB | None | 0 0
  1. -*- Introdução -*-
  2. Nesse procedimento vou documentar o que eu fiz para
  3. criar um initrd customizado. Os unicos motivos para você precisar de
  4. um initrd - que eu conheço - são: - Quando deseja bootar por LABEL ou
  5. UUID (meu caso) - Quando o /usr fica em uma partição diferente da do /
  6. - Quando o driver de disco onde sua partição / fica foi compilado como
  7. modulo.
  8.  
  9. Fora esses casos - e algum outro que eu disconheça - você não precisa de um initrd.
  10.  
  11. Nesse procedimento eu vou criar o initrd, na "UNHA", é possivel - e
  12. mais indicado - usar ferramentas para o mesmo. Das que eu ja usei o
  13. Dracut [1] foi o que mais me agradou.
  14.  
  15. Um initrd, initramdisk ou initramfs é uma estrurura de diretorios
  16. epacotada com cpio e compressa com gzip. Essa estrutura é como se
  17. fosse um mini-sistema. Durante o processo de boot o kernel "explode"
  18. esse arquivo e executa o script /init. O /init tem como principal
  19. resposabilidade montar o / real e fazer um chroot para o mesmo. Para
  20. montar o root podem haver dependencias, por exemplo no meu caso, eu
  21. quero confiar somente no LABEL e não num path /dev/sdX, por isso
  22. preciso executar um comando para achar o meu fs baseando-me no LABEL
  23. antes de montar o /.
  24.  
  25. Estou criando esse guia porque perdi cerca de 3 horas por causa de
  26. detalhes. E da proxima vez não quero perder meu tempo tentando
  27. desvenda-los de novo. E aproveito para passar o conhecimento para
  28. frente..
  29.  
  30. -*- Dependencias -*-
  31.  
  32. Para executar esse procedimento você precisa ter instalado os binarios
  33. abaixo:
  34.  
  35. gzip
  36. cpio
  37. findfs (para bootar por LABEL)
  38. busybox
  39.  
  40. -*- Procedimento -*-
  41.  
  42. NOTA: Todos os procedimentos aqui foram executados como root.
  43.  
  44. 1. Crie um diretorio que vai hospedar toda a estrutura do ram disk.
  45. # mkdir initramfs
  46.  
  47. 2. Crie a estrutura de diretorios
  48. # cd initramfs
  49. # mkdir -p bin lib dev etc mnt/root proc root sbin sys
  50.  
  51. 3. Copie e instale o busybox
  52. # cd bin
  53. # cp -aL /usr/bin/busybox .
  54. # busybox --install .
  55.  
  56. Isso vai criar uma serie de arquivos com os nomes dos binarios mais
  57. usados. Verifique que foram instalados com sucesso
  58. # ls -l
  59.  
  60. 4. Populando o initrd
  61.  
  62. A grande maioria dos binarios depende de alguma(s) bibliotecas, com o
  63. busybox não é diferente. O comando ldd serve para exibir essas
  64. dependencias.
  65.  
  66. # cd
  67. # ldd initramfs/bin/busybox
  68. linux-gate.so.1 => (0xb77e6000)
  69. libpam_misc.so.0 => /lib/libpam_misc.so.0 (0xb77a5000)
  70. libc.so.6 => /lib/libc.so.6 (0xb7656000)
  71. libpam.so.0 => /lib/libpam.so.0 (0xb7649000)
  72. /lib/ld-linux.so.2 (0xb77ca000)
  73. libdl.so.2 => /lib/libdl.so.2 (0xb7645000)
  74.  
  75. Precisamos copiar cada lib para o diretorio lib do nosso initramfs o
  76. unico que não é necessario é o linux-gate.so.1.
  77.  
  78. # cd initramfs/lib
  79. # cp -aL /lib/libpam_misc.so.0 .
  80. # cp -aL /lib/libc.so.6 .
  81. # cp -aL /lib/libpam.so.0 .
  82. # cp -aL /lib/ld-linux.so.2 .
  83. # cp -aL /lib/libdl.so.2 .
  84.  
  85. Para verificar que tudo está OK, configure o LD_LIBRARY_PATH para o
  86. diretorio lib e execute o ldd novamente. O ld-linux é o unico que vai
  87. aparecer sob /lib. E o linux-gate pode ser ignorado.
  88.  
  89. # export LD_LIBRARY_PATH=/root/initramfs/lib
  90. # ldd /root/initramfs/bin/busybox
  91. linux-gate.so.1 => (0xb772f000)
  92. libpam_misc.so.0 => /root/initramfs/lib/libpam_misc.so.0 (0xb770e000)
  93. libc.so.6 => /root/initramfs/lib/libc.so.6 (0xb75bf000)
  94. libpam.so.0 => /root/initramfs/lib/libpam.so.0 (0xb75b2000)
  95. /lib/ld-linux.so.2 (0xb7713000)
  96. libdl.so.2 => /root/initramfs/lib/libdl.so.2 (0xb75ae000)
  97. # unset LD_LIBRARY_PATH
  98.  
  99. Colocarei tambem o findfs, responsavel por encontrar a partição a partir de um LABEL.
  100. # ldd /sbin/findfs
  101. linux-gate.so.1 => (0xb7789000)
  102. libblkid.so.1 => /lib/libblkid.so.1 (0xb7728000)
  103. libc.so.6 => /lib/libc.so.6 (0xb75d9000)
  104. libuuid.so.1 => /lib/libuuid.so.1 (0xb75d3000)
  105. /lib/ld-linux.so.2 (0xb776d000)
  106. # cp /sbin/findfs /root/initramfs/sbin/.
  107. # cd /root/initramfs/lib
  108. # cp -aL /lib/libblkid.so.1 .
  109. # cp -aL /lib/libc.so.6 .
  110. # cp -aL /lib/libuuid.so.1 .
  111. # cp -aL /lib/ld-linux.so.2 .
  112.  
  113.  
  114. Caso você deseje colocar algum outro binario no initrd precisa
  115. executar o mesmo procedimento apontado acima. Alem das libs, alguns
  116. binarios dependem de outros arquivos, como arquivos de configuração
  117. etc. Não se esqueça que muitos binarios dependem de pacotes. Por
  118. exemplo o vim depende do ncurses. Para descobrir os arquivos que um
  119. binario tenta abrir durante seu startup - usarei o vim no exemplo -
  120. execute o comando abaixo.
  121.  
  122. # LC_ALL=C
  123. # strace -o vim-open-syscalls -e vim
  124.  
  125. Lembre-se de executar o comando abaixo em um tty, assim você está mais
  126. proximo do que vai encontrar durante o boot. O arquivo
  127. vim-open-syscalls vai conter todas as chamadas a open do vim, contento
  128. os arquivos usados como parametros. Você precisa usar seu bom senso
  129. aqui, nem tudo é extritamente necessario para o vim funcionar.
  130.  
  131. Para validar que o initrd esta OK, execute o comando abaixo.
  132. # chroot /root/initramfs /bin/sh
  133.  
  134. Se o shell abrir está tudo OK. Você deve testar os otros binarios,
  135. caso haja algum, também. Se você receber um "No such file or
  136. directory" significa que alguma lib está faltando, impedindo o binario
  137. de subir.
  138.  
  139. É bom colocar os modulos do kernel no initrd, para isso execute os
  140. comandos abaixo.
  141.  
  142. # cd /root/initramfs
  143. # tar vcO /lib/modules/$(uname -r)/kernel/drivers/ | tar vx
  144.  
  145.  
  146. 5 Crie o script init
  147.  
  148. Segue abaixo o script init que eu estou usando. Esse script deve ficar
  149. na rais do initrd, no meu caso é /root/initramfs/init.
  150.  
  151. ------------- INICIO DO init ---------------
  152. #!/bin/busybox sh
  153.  
  154. rescue_shell() {
  155. echo "Something went wrong. Dropping you to a shell."
  156. exec /bin/sh
  157. }
  158.  
  159. uuidlabel_root() {
  160. for cmd in $(cat /proc/cmdline) ; do
  161. case $cmd in
  162. root=*)
  163. dev=${cmd#root=}
  164. type=${dev%%=*}
  165. if [ $type = "LABEL" ] || [ $type = "UUID" ] ; then
  166. mount -o ro $(findfs "$dev") /mnt/root
  167. else
  168. mount -o ro ${dev} /mnt/root
  169. fi
  170. ;;
  171. esac
  172. done
  173. }
  174.  
  175.  
  176. # Mount the /proc and /sys filesystems.
  177. mount -t proc none /proc
  178. mount -t sysfs none /sys
  179.  
  180. # Do your stuff here.
  181. echo "This script mounts rootfs and boots it up, nothing more!"
  182.  
  183. mount -t devtmpfs none /dev
  184.  
  185. uuidlabel_root || rescue_shell
  186.  
  187. # Clean up.
  188. umount /proc
  189. umount /sys
  190. umount /dev
  191.  
  192. # Boot the real thing.
  193. exec switch_root /mnt/root /sbin/init
  194. ------------- FIM DO init ---------------
  195.  
  196. De permição de execução para o init
  197. # chmod +x /root/initramfs/init
  198.  
  199. Durante o processo de boot, o initrd é explodido no /, o falso /,
  200. entao o script init é executado sob esse "mini-sistema". Ele é
  201. reponsavel por encontrar o / real, monta-lo e então executar um
  202. swich_root para o / real.
  203.  
  204. 6 Configuração do kernel
  205. NOTA: Se você ja usa um initrd então seu kernel já tem suporte e você pode pular essa sessão.
  206.  
  207. O suporte ao inird é dado pela opção CONFIG_BLK_DEV_INITRD. Execute o
  208. comando abaixo no arquivo config do seu kernel para saber se ele tem
  209. suporte ao initrd
  210.  
  211. # grep INITRD config-SEU_KERNEL
  212.  
  213. O config geralmente pode ser encontrado em /boot, com o nome
  214. config-<SEU_KERNEL>. Se não estiver no /boot, procure no
  215. /usr/src/linux por .config. Se mesmo assim não tiver procure por
  216. /proc/config.gz.. Esse arquivo é um zipado do config mantido dentro do
  217. /proc, provavelmente entao execute
  218.  
  219. # zgrep INITRD /proc/config.gz
  220.  
  221. Se você não encontrou em nenhum dos casos acima, a sua unica opção é
  222. compilar o kernel novamente par ter certeza de que ele suporta o
  223. initrd. A opção pode ser encontrada em
  224.  
  225. General Setup ------>
  226. Initial RAM filesystem and RAM disk ..
  227.  
  228. Aproveite e abilite as opções abaixo também. Assim você tem acesso ao
  229. config pelo /proc/config.gz
  230.  
  231. <*> Kernel .config support
  232. [*] Enable access to .config through /proc/config.gz
  233.  
  234. 7. Empacotando o initrd.
  235.  
  236. Execute o comando abaixo para empacotar o initrd, ja no diretorio
  237. /boot, coloque o nome que prefirir, mas lembre que esse nome sera
  238. usado no menu.lst do grub no passo seguinte.
  239.  
  240. # cd /root/initramfs
  241. # find . -print0 | cpio --null -ov --format=newc | gzip -9 > /boot/gkos-initramfs.cpio.gz
  242.  
  243. 8. No grub
  244.  
  245. ATENÇÃO: Não edite o bloco do grub que ja funciona! Em vez disso copie
  246. e cole e edite a copia. Do contrario você pode acabar com uma unica
  247. opção - que não funcina - na hora do boot.
  248.  
  249. Crie um novo bloco - no arquivo /boot/grub/menu.lst - contendo o
  250. initrd. Veja como ficou o meu:
  251.  
  252. # gentoo 3.3.8 with initrd
  253. title gentoo-3.3.8 initrd
  254. root (hd0,0)
  255. kernel /boot/gentoo-3.3.8 root=LABEL=gentoo-Root ro
  256. initrd /boot/gkos-initramfs.cpio.gz
  257.  
  258. 9. Reboot
  259.  
  260. Salve tudo, faça o double check padrão e reboot a maquina. Selecione a
  261. nova opção no grub e cruse os dedos.
  262.  
  263. -*- Referencias -*-
  264. http://en.gentoo-wiki.com/wiki/Initramfs
  265. [1] https://dracut.wiki.kernel.org/index.php/Main_Page
Advertisement
Add Comment
Please, Sign In to add comment