bzImage
#Gnu/Linux, Planet Libre
Boot d'un kernel bzImage sur les anciennes versions de Xen < 3.4
Juste un petit arcticle, qui me sert d'aide mémoire.
Je suis tombé sur un problème:
J'ai voulut booter un DomU à base de Ubuntu 10.04LTS sur un système de virtualisation Xen 3.1
En l'ocurence il s'agissait d'une Distri SLES10SP4 + Xen 3.1
Je pensais que cela ne poserai aucun problème, j'utilise mon template DomU Ubuntu10.04LTS depuis un petit moment déjà sur des Xen plus récent.
En voulant booter ce fameux domU j'ai eut droit à l'erreur suivante:
Error: (2, 'Invalid kernel', 'xc_dom_find_loaderJ'ai cherché un bon moment, c'est comme si le Kernel n'était pas reconnu.
Et en fait je suis tombé sur cette page: https://www.globalways.net/blog/archives/76-Extracting-bzImage-from-vmlinuz.html
Il explique que Les anciennes versions de Xen ne supporte pas les nouveaux formats d'image du noyau. Wikipedia affirme que "Aucun outil spécifique existe pour décompresser le fichier bzImage».
En effet sous Ubuntu depuis la 9.10, le kernel n'est plus un simple fichier gzipé mais un bzImage.
root@ubuntults:/boot# file vmlinuz-2.6.32-37-server
vmlinuz-2.6.32-37-server: Linux kernel x86 boot executable bzImage, version 2.6.32-37-server (buildd@allspi, RO-rootFS, root_dev 0x6801, swap_dev 0x3, Normal VGA
On voit bien que le Kernel est un bzImage.
On sait que ce fameux bzimage commence par une entête spécifique. et que après il y a l'entête de gzip qui est:
ID1 0x1f
ID2 0x8b
CM 0x08 (Compression Method deflate=)
FLG 0x00 (no extra fields)
Le but: supprimer tout ce qui se trouve avant cette entête afin d'avoir un kernel basique.
Pour cela, 2 méthodes:
Celle décrite dans la page web, grace à binoffset::
L'auteur à développer une commande qui permet de trouver ce fameux offset et d'en donner son emplacement en octet
La commande est présente ici:
http://svn.opentom.org/opentom/trunk/linux-2.6/scripts/binoffset.c
Après l'avoir compilé.
gcc -o binoffset binoffset.cOn peut utiliser la commande dd:
root@ubuntults:/boot# dd if=vmlinuz-2.6.32-37-server bs=1 skip=$(/root/binoffset vmlinuz-2.6.32-37-server 0x1f 0x8b 0x08 0x0) of=vmlinuz-2.6.32-37-server-UNPACK.gzOn lit le kernel en bs de 1octet on skeep 14441 octets ( qui correspondent au debut du fichier jusqu'a ce fameux offset ) autrement dit on aura supprimer tout l'entete du bzimage et on aura un kernel gzip classique.
filesize: 4110432
number of pattern matches = 1
14441
4095991+0 records in
4095991+0 records out
4095991 bytes (4.1 MB) copied, 15.2127 s, 269 kB/s
Une fois dézippé on voit bien qu'on a kernel classique.
root@ubuntults:/boot# file vmlinuz-2.6.32-37-server-UNPACK.gz
vmlinuz-2.6.32-37-server-UNPACK.gz: gzip compressed data, from Unix,
last modified: Fri Dec 2 22:02:53 2011, max compression
root@ubuntults:/boot# gunzip vmlinuz-2.6.32-37-server-UNPACK.gz
gzip: vmlinuz-2.6.32-37-server-UNPACK.gz: decompression OK, trailing
garbage ignored
root@ubuntults:/boot# file vmlinuz-2.6.32-37-server-UNPACK
vmlinuz-2.6.32-37-server-UNPACK: ELF 64-bit LSB executable, x86-64,
version 1 (SYSV), statically linked, stripped
D'ailleurs ce kernel est reconnu aussi bien gzipé ou pas.
Méthode en bash (moins sure):
J'aurais aimé faire cela avec des commandes système basiques sans rien avoir à installer...
Après maintes commande j'ai fait ce que je voulais avec la commande suivante...
root@ubuntults:/boot# a=$(cat vmlinuz-2.6.32-37-server | xxd -g1 | grep "1f 8b 08 00" | awk -F":" '{print $1}' | sed 's/^[0\t]*//'); b=$(cat vmlinuz-2.6.32-37-server | xxd -g1 | grep "1f 8b 08 00" | awk -F":" '{print $2}' | awk -F"1f 8b 08 00" '{print $1}'| awk '{x=x+NF}END{print x}'); c=$(( $a + $b )); echo Hexa=$c ; echo Decimal=$((0x$c))
Hexa=3869
Decimal=14441
le même dd:
dd if=vmlinuz-2.6.32-37-server bs=1 skip=14441 of=vmlinuz-2.6.32-37-server-UNPACK2.gzJe n'ai as testé en profondeur, cette commande ne fonctionne pas forcément partout à mon avis.
30 janvier 2012
Aucun commentaire