Affichage des articles dont le libellé est Système. Afficher tous les articles
Affichage des articles dont le libellé est Système. Afficher tous les articles

dimanche 5 novembre 2023

Disque externe bootable legacy et uefi

J'ai un disque dur externe usb que j'ai formaté de manière à ce qu'il puisse booter aussi bien de manière traditionnelle (legacy)  que en mode uefi:

toto@aldebaran:~$ sudo fdisk -l /dev/sda
[sudo] Mot de passe de toto: 
Disque /dev/sda : 447,13 GiB, 480103981056 octets, 937703088 secteurs
Disk model: 80G2G0A-00JH30  
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 4096 octets
taille d'E/S (minimale / optimale) : 4096 octets / 4096 octets
Type d'étiquette de disque : gpt
Identifiant de disque : 6B6A3B5A-81C8-479D-B261-B4733B4D0D70

Périphérique     Début       Fin  Secteurs Taille Type
/dev/sda1         2048      4095      2048     1M Amorçage BIOS
/dev/sda2         4096   2101247   2097152     1G Système EFI
/dev/sda3      2101248  18878463  16777216     8G Partition d'échange Linux
/dev/sda4     18878464 102764543  83886080    40G Système de fichiers Linux
/dev/sda5    102764544 186650623  83886080    40G Système de fichiers Linux
/dev/sda6    186650624 937701375 751050752 358,1G Système de fichiers Linux
michel@pc-linuxshop-A7K57UJU:~$ 

Grub s'installe dans sda1 dans le cas d'un amorçage en mode traditionnel, sda2 est monté dans /boot/efi pour un amorçage en mode UEFI.
J'ai installé un système linux (linux mint)  sur ce disque USB, à partir d'un laptop dont le boot est legacy.
Pas de souci lorsqu'il est branché sur un ordinateur qui s'amorce à l'ancienne. Par contre si ce disque dur externe est branché sur un ordinateur dont l'amorçage est UEFI, il n’apparaît pas dans la liste des périphériques sur les quels on peut booter.
Depuis un ordinateur UEFI où est installé Ubuntu (22.04), je lance les commandes suivantes:

sudo mount /dev/sda4 /mnt
sudo mount /dev/sda2 /mnt/boot/efi 
for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt/$i; done  
sudo mount --bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
sudo chroot /mnt
grub-install 
update-grub
exit  
sudo umount /dev/sda2
sudo umount /dev/sda4

(/dev/sda4 contient la racine de linx mint avec lequel je veux démarrer mon disque USB.)
Mais déception: ça ne fonctionne pas.
Le disque possède le drapeau pmbr_boot, ce qui pose problème.
Il faut enlever ce drapeau:

toto@aldebaran:~$ sudo parted /dev/sda
(parted) disk_set pmbr_boot off
(parted) quit

Et voilà, le problème est résolu. 

vendredi 1 septembre 2023

Blscfg et Fedora

Fedora utilise par défaut BLSCFG (Boot Loader Specification Configuration) comme on peut le vérifier dans le fichier /etc/defaults/grub qui contient GRUB_ENABLE_BLSCFG=true. De ce fait /boot/grub2/grub.cfg ne contient aucune entrée menuentry pour Fedora, mais seulement des entrées pour les autres systèmes d'exploitation.

Par contre on y trouve: 

insmod

blscfg

La commande blscfg ajoute des entrées au menu en se basant sur le contenu du dossier /boot/loader/entries. Ici le dossier contient 4 fichiers:

[toto@fedora ~]$ sudo ls -1 /boot/loader/entries 
7753b84a2ac148e7894de73d56d9be39-0-rescue.conf
7753b84a2ac148e7894de73d56d9be39-6.4.11-200.fc38.x86_64.conf
7753b84a2ac148e7894de73d56d9be39-6.4.12-200.fc38.x86_64.conf
7753b84a2ac148e7894de73d56d9be39-6.4.9-200.fc38.x86_64.conf

J'examine le contenu d'un des fichiers:

[toto@fedora ~]$ sudo -i
[sudo] Mot de passe de toto : 
[root@fedora ~]# cd /boot/loader/entries
[root@fedora entries]# cat 7753b84a2ac148e7894de73d56d9be39-6.4.12-200.fc38.x86_64.conf 
title Fedora Linux (6.4.12-200.fc38.x86_64) 38 (Workstation Edition)
version 6.4.12-200.fc38.x86_64
linux /boot/vmlinuz-6.4.12-200.fc38.x86_64
initrd /boot/initramfs-6.4.12-200.fc38.x86_64.img
options root=UUID=a7465ac8-7427-4c7b-a2f4-3b6dcb9fcfae ro resume=UUID=f17ebeb2-0767-4f7c-ba74-5ba3ed6acb92 rhgb quiet 
grub_users $grub_users
grub_arg --unrestricted
grub_class fedora
[root@fedora entries]# 

Pour une raison ou une autre, je veux ne pas utiliser blscfg. Donc dans /etc/defaults/grub je mets:

GRUB_ENABLE_BLSCFG=false

Ensuite je regénère grub.cfg avec la commande

[toto@fedora ~]$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Tout va bien jusqu'au prochain changement de noyau:
catastrophe: kernel panic
Il faut alors booter sur le noyau précédent pour réparer les dégâts. Si j’examine grub.cfg, je constate que dans la commande linux qui permet de booter sur le nouveau noyau se trouve:
root=/dev/sdb5 (dans mon cas) au lieu de root=UUID=.....
Pour régler le problème, il suffit de régénérer grub.cfg comme précédemment. Il n'est même pas nécessaire de rebooter: on peut procéder dès que l'update est terminé.


samedi 9 janvier 2016

Google-earth Fedora vs openSuse

Comme je l'ai indiqué dans le billet précédent, le paquet téléchargé ici pour Fedora 64 bits (à savoir le paquet google-earth-stable_current_x86_64.rpm) n'est pas installable suite à un conflit avec le fichier /usr/bin du paquet filesystem.
J'ai expliqué comment remédier à ce problème: supprimer la ligne

%dir %attr(0755, root, root) "/usr/bin"

dans le fichier spec du paquet (voir le billet précédent).

Cependant sur la page de téléchargement on peut constater que le paquet destiné à openSuse est le même que celui pour Fedora.
Et dans openSuse, l'installation de ce même paquet ne pose aucun problème!
Quel est ce mystère?
La réponse se trouve du côté du fichier /usr/bin fourni par filesystem.
Dans openSuse:




Les droits sur /usr/bin sont du type 0755, exactement comme dans le fichier spec.

Dans Fedora (23):




Les droits ne correspondent plus: ils valent 0555 ce qui provoque le conflit.

Plutôt que de supprimer la ligne litigieuse du fichier spec, il suffit de la modifier.


Donc je lance la commande


toto@rigel:~/Téléchargements$ rpmrebuild -p -e google-earth-stable_current_x86_64.rpm 

Ensuite dans l'éditeur qui s'ouvre (normalement c'est vi), je trouve la ligne ad hoc avec

/usr\/bin

J'amène à l'aide des flèches le curseur sur le 7, puis:

r5
:wq

A la question qui vient, je réponds que je veux continuer, ce qui provoque la création d'un nouveau paquet qu'il suffit d'installer.


 

mardi 8 décembre 2015

Mise à niveau vers Fedora 23

Je suis passé de Fedora 22 à Fedora 23 à l'aide des commandes suivantes:

[root@rigel ~]# dnf update --refresh

pour mettre à jour le système existant

[root@rigel ~]# dnf install dnf-plugin-system-upgrade

pour installer le programme qui convient

 [root@rigel ~]# dnf system-upgrade download --releasever=23

pour télécharger les paquets de la nouvelle version

[root@rigel ~]# dnf system-upgrade reboot

pour procéder à l'installation proprement dite.

En principe il n'y a pas de soucis.

Cependant si vous avez procédé à l'installation de chromium et de pepper-flash suivant ce qui est préconisé ici, il ne faut pas oublier de réactiver les dépôts russianfedora-free:

[root@rigel ~]# sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/russianfedora-free.repo

[root@rigel ~]# sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/russianfedora-free-updates.repo

En ce qui concerne google-earth, si un dépôt est configuré et activé, il faut le supprimer:

[root@rigel ~]# rm /etc/yum.repos.d/google-earth.repo

sous peine d'avoir une erreur qui empêche la mise à jour (c'est la même que celle dont il est question ci-après).

Le paquet téléchargé ici pour Fedora 64 bits (à savoir le paquet google-earth-stable_current_x86_64.rpm) n'est pas installable car:

Erreur : Erreur du contrôle de transaction
  le fichier /usr/bin de l'installation de google-earth-stable-7.1.4.1529-0.x86_64 entre en conflit avec le fichier du paquet filesystem-3.2-35.fc23.x86_64

Cette commande:

toto@rigel:~/Téléchargements$ rpmrebuild -p -s fichier google-earth-stable_current_x86_64.rpm && grep '/usr/bin' fichier
%dir %attr(0755, root, root) "/usr/bin"
%attr(0777, root, root) "/usr/bin/google-earth"

nous montre où est le problème: il faut supprimer la première ligne de l'output.

Je lance la commande:

toto@rigel:~/Téléchargements$ rpmrebuild -p -e google-earth-stable_current_x86_64.rpm 

qui donne la possibilité de modifier le fichier spec.

En principe l'éditeur est est vi. On y tape successivement les commandes

/usr\/bin
dd
:wq

A la question posée (veux-t-on continuer) la réponse à fournir est évidemment 'Oui', ce qui provoque la création d'un nouveau rpm qu'il reste à installer:

[root@rigel ~]# dnf install /home/toto/rpmbuild/RPMS/x86_64/google-earth-stable-7.1.4.1529-0.x86_64.rpm 

Pour que la recherche d'un lieu dans google-earth fonctionne correctement j'ai créé un alias:

alias google-earth='LC_NUMERIC=C google-earth'

(commande que j'ai mise dans mon fichier .bashrc)

Le lancement de google-earth en ligne de commande produit une série de messages d'erreurs:

1208/114257:ERROR:nss_ocsp.cc(581)] No URLRequestContext for OCSP handler.

Cependant google-earth ne crashe pas.

Si c'est le cas, il suffit de supprimer le dossier .googleearth:

[toto@rigel ~]$ rm -rf .googleearth/



mardi 2 juin 2015

souris qui s'endort

Quoi de plus énervant que d'avoir une souris qui s'endort tout le temps: après quelques secondes d'inactivité, il faut chaque fois la réveiller avec un clic.
Essayons de trouver la source du problème.
Utilisons tout d'abord lsusb:

[toto@rigel ~]$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0461:4d64 Primax Electronics, Ltd 
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
[toto@rigel ~]$ 

La deuxième ligne correspond à notre souris.

Cherchons des infos sur le descripteur de périphérique /dev/bus/usb/002/002

[toto@rigel ~]$ udevadm info /dev/bus/usb/002/002 
P: /devices/pci0000:00/0000:00:02.0/usb2/2-3
N: bus/usb/002/002
E: BUSNUM=002
E: DEVNAME=/dev/bus/usb/002/002
E: DEVNUM=002
E: DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-3
E: DEVTYPE=usb_device
E: DRIVER=usb
E: ID_BUS=usb
E: ID_MODEL=USB_Optical_Mouse
E: ID_MODEL_ENC=USB\x20Optical\x20Mouse
E: ID_MODEL_ID=4d64
E: ID_REVISION=0200
E: ID_SERIAL=0461_USB_Optical_Mouse
E: ID_USB_INTERFACES=:030102:
E: ID_VENDOR=0461
E: ID_VENDOR_ENC=0461
E: ID_VENDOR_FROM_DATABASE=Primax Electronics, Ltd
E: ID_VENDOR_ID=0461
E: MAJOR=189
E: MINOR=129
E: PRODUCT=461/4d64/200
E: SUBSYSTEM=usb
E: TYPE=0/0/0
E: USEC_INITIALIZED=201152
[toto@rigel ~]$ 

(En gras ce que nous allons utiliser pour la suite)

Vérifions le contenu du fichier power/control adéquat:

[toto@rigel ~]$ cat /sys/bus/usb/devices/2-3/power/control
auto
[toto@rigel ~]$ 

Sur cette machine, plusieurs distributions sont installées. Cette fois nous sommes dans Manjaro. Pour d'autres distributions où la souris fonctionne correctement, le même fichier contient on.
De ce fait nous essayons

[root@rigel ~]# echo "on" > /sys/bus/usb/devices/2-3/power/control
[root@rigel ~]# 

qui résout instantanément le problème, mais jusqu'au prochain boot seulement

Pour une solution définitive ajoutons la règle

ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0461", ATTR{idProduct}=="4d64", TEST=="power/control", ATTR{power/control}="on"

nommée usb-power.rules dans /etc/udev/rules.d, puis nous redémarrons le système.

Caramba, ça ne fonctionne pas!

Vérifions ce qu'il en est en lançant la commande:

[root@rigel ~]# udevadm test /bus/usb/devices/2-3  2>&1 | grep writing

Nous redirigeons le canal 2 vers le canal 1 afin que tout soit filtré par grep (plus d'infos sur les redirections dans ce billet), car la plus grande partie du flux de sortie de la commande udevadm transite par le canal 2 (qui n'est pas filtré par grep).

Le résultat en image:


Donc power/control est effectivement mis sur on et la souris fonctionne aussitôt la commande exécutée (bien qu'il s'agisse d'un test).
La règle ajoutée joue bien son rôle. Le mystère reste entier.

Cependant:

[root@rigel ~]# udevadm test /bus/usb/devices/2-3  2>/dev/null | tail -1
run: 'lmt-udev force modules=runtime-pm devices=2-3'
[root@rigel ~]# 

Le responsable ne serait-il pas lmt-udev qui s'exécute en dernier, après application de toutes les règles?
Si lmt-udev est le responsable, pourquoi cette fois la souris ne s'endort elle plus?
Mais sans doute parce-qu'il s'agit d'un test et que lmt-udev n'est pas exécuté.
D'ailleurs nous sommes prévenu:

[root@rigel ~]# udevadm test /sys/bus/usb/devices/2-3 2>/dev/null | head -3
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

D'autre part:

[toto@rigel ~]$ udevadm test /sys/bus/usb/devices/2-3  2>&1 1>/dev/null | grep 'RUN'
RUN 'lmt-udev force modules=runtime-pm devices=%k' /usr/lib/udev/rules.d/99-laptop-mode.rules:3
toto@rigel ~]$ awk 'NR==3' /usr/lib/udev/rules.d/99-laptop-mode.rules
ACTION=="add|remove", SUBSYSTEM=="usb", RUN+="lmt-udev force modules=runtime-pm devices=%k"

/usr/lib/udev/lmt-udev est bien un programme spécifié par une clef RUN (règle 3 de 99-laptop-mode.rules). C'est un script qui appelle /usr/bin/laptop_mode.
Après quelques recherches nous trouvons le fichier /etc/laptop-mode/conf.d/runtime-pm.conf dans lequel nous pouvons mettre notre souris sur une blacklist:

# The list of Device IDs that should not use autosuspend. Use system commands or
# look into sysfs to find out the IDs of your devices.
# Example: AUTOSUSPEND_DEVID_BLACKLIST="046d:c025 0123:abcd"
AUTOSUSPEND_RUNTIME_DEVID_BLACKLIST="0461:4d64"

Dans le même fichier on pourrait à la place blacklister le pilote usb:

# The list of device driver types that should not use autosuspend.  The driver
# type is given by "DRIVER=..." in a device's uevent file.
# Example: AUTOSUSPEND_DEVID_BLACKLIST="usbhid usb-storage"
AUTOSUSPEND_RUNTIME_DEVTYPE_BLACKLIST="usb"


Le problème est résolu!

samedi 23 novembre 2013

Connexion IPv6 à un serveur PostgreSQL

A la fin de ce billet (maintenant en partie obsolète), nous avons expliqué comment réaliser une connexion IPv4 entre un serveur PostgreSQL et une machine client située sur un réseau local.
Nous allons cette fois expliquer comment procéder pour une connexion IPv6.
Tout d'abord il s'agit d'adapter le fichier pg_hba.conf (situé sur le serveur).
Voici un extrait d'un tel fichier modifié en conséquence:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     peer  map=map01
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident map=map01
# IPv4 lan connections
host    all             all             192.168.1.0/24          md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# IPv6  lan connections
host    all             all             fe80::/10               md5

(en bleu ce qui concerne les connexions réseau IPv4, en rouge les connexions IPv6)

Évidemment avec un tel fichier pg_hba.conf, pg_ident.conf doit contenir ce qui convient, par exemple:

# MAPNAME       SYSTEM-USERNAME         PG-USERNAME
map01           toto                    toto
map01           toto                    titine

pour que toto puisse se connecter lui-même ou en tant que titine.

Mais ceci nous éloigne du sujet, d'autant plus que les connexions qui nous intéressent ne sont pas concernées.

Revenons aux connexions réseau: les modifications à effectuer sur le fichier postgresql.conf sont les mêmes que celles présentées auparavant:

# - Connection Settings -
listen_addresses = '*' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432 # (change requires restart)

Si nous toutefois nous voulons accepter exclusivement les connexions IPv6, il suffit par exemple de remplacer

listen_addresses = '*'
par:
listen_addresses = '::'

Si un pare-feu est actif, il reste à y effectuer quelques petits aménagements.
Nous pouvons procéder avec gufw via l'onglet avancé du panneau 'Ajouter des règles":



Pour IPv4, nous ajoutons cette règle:


et pour IPv6 celle-ci:


Nous aurions pu agir en ligne de commande avec les commandes:

# ufw allow in from 192.168.1.0/24 to any port postgresql

# ufw allow in from fe80::/10 to any port postgresql

# ufw reload

Si le serveur est un serveur Fedora (utilisant firewalld), les commandes équivalentes sont:


firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="192.168.1.0/24" service name="postgres" accept'

# firewall-cmd --permanent --add-rich-rule 'rule family="ipv6" source address="fe80::/10" service name="postgres" accept'

# firewall-cmd --reload

En IPv4, nous avons configuré la connexion réseau de notre serveur pour que celui-ci dispose d'une adresse IP fixe (située dans une plage qui n'est pas accessible au serveur DHCP):


Nous pouvons connecter un terminal psql avec la commande
psql bd01 -h 192.168.1.2
(connexion de l'utilisateur courant à la base de données bd01).
Si dans le fichier /etc/hosts du poste client nous avons ajouté l'entrée:
192.168.1.2   rigel
(rigel étant le nom d'hôte de la machine serveur)
on peut alors utiliser la commande
psql bd01 -h rigel

(Rappelons que le mot de passe demandé est un mot de passe PostgreSQL et non un mot de passe système)

Pour se connecter en IPv6, il faut utiliser une autre adresse.
Cherchant des infos sur la connexion, nous obtenons ceci:

Mais l'adresse IPv6 qui apparaît ici n'est pas celle à utiliser: elle est destinée aux communications vers l'extérieur et de plus elle est temporaire.
La ligne de commande nous donne plus d'infos:

toto@rigel:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr f4:6d:04:b6:41:4c 
          inet adr:192.168.1.2  Bcast:192.168.1.255  Masque:255.255.255.0
          adr inet6: 2a02:a03f:2082:2500:785e:2571:1adf:b2b6/64 Scope:Global
          adr inet6: 2a02:a03f:2082:2500:f66d:4ff:feb6:414c/64 Scope:Global
          adr inet6: fe80::f66d:4ff:feb6:414c/64 Scope:Lien

                    .................................

Nous découvrons l'existence d'une deuxième adresse IPv6 (adr inet6) destinée aux communications vers l'extérieur mais dont l'utilisation n'est pas privilégiée car elle est construite sur base de l'adresse matérielle.
La 3ième adresse IPv6 (également construite sur base de l'adresse matérielle) est celle qui nous intéresse.
Cependant la commande
 psql bd01 -h fe80::f66d:4ff:feb6:414c
produit le message d'erreur "psql: could not connect to server: Argument invalide":


L'astuce est qu'il faut faire suivre l'adresse de % puis de l'interface à utiliser (par exemple wlan0)pour atteindre la cible:


 Il faut procéder de même pour établir une connexion avec libreoffice:



Nous aimerions maintenant utiliser le nom d'hôte comme en IPv4.
Pour ce faire ajoutons dans le fichier /etc/hosts  du poste client la ligne 

fe80::f66d:4ff:feb6:414c    rigel6

Procédons:

 
Le message reçu est le même que pour la commande

 psql bd01 -h fe80::f66d:4ff:feb6:414c

Mais cette fois ajouter %wlan0 ne nous est d'aucun secours. On reçoit le message:

psql: could not translate host name "rigel6%wlan0" to address: Nom ou service inconnu

Nous pouvons contourner le problème en plaçant dans /usr/local/bin un script (que nous appelons ah et rendu exécutable avec la commande chmod +x) contenant:

#!/bin/sh

awk -v "var=$1" '$2 == var {print $1 "%wlan0"}' /etc/hosts

$1, paramètre transmis au script (rigel6) est sauvegardé dans var.
Ensuite $1 et $2 contiennent les champs de chaque ligne lue par awk.
L'action (print) est exécutée lorsque $2 vaut rigel6.

Vérifions que ça fonctionne:


Bingo!
Cependant ce moyen est inopérant sur l'écran de connexion libreoffice.
Il faut donc saisir pour se connecter à bd01

dbname:bd01 host=fe80::f66d:4ff:feb6:414c%wlan0

mais cela ne doit être effectué qu'une seule fois: lors de la création du fichier odb
 

dimanche 28 octobre 2012

Clef de secours (seconde partie)

Suivant les indications figurant dans le billet Clef de secours, nous avons rendu une clef usb bootable en installant dans son secteur d'amorce un chargeur grub qui pointe vers un dossier grub situé sur cette même clef.
Dans ce dossier se trouve un fichier de configuration grub.cfg contenant par exemple:
search --no-floppy --label --set=root Ubuntu 
chainloader +1 
boot
Si tout fonctionne bien, booter via la clef est transparent et le menu qui surgit est celui du fichier de configuration utilisé par le chargeur grub dont la partie initiale se trouve sur le VBR (Volume Boot Record) de la première partition trouvée dont le label est "Ubuntu".
Dans le cas contraire, si cela se passe mal, il existe diverses possibilités. L'une d'elles consiste à ce que l'on atterrisse directement dans un shell grub.
Nous sommes alors à la tête d'un mini-système d'exploitation et nous pouvons lancer au niveau de ce shell grub un certain nombre de commandes, dont la commande set qui renvoie la liste de différentes variables d'environnement avec leur valeur.
Examinant l'output de cette commande nous y trouvons quelque chose comme:
prefix=(hd0,msdos1)/grub
root=hd1,msdos3
Cela montre que l'exécution de la commande search a été couronnée de succès car au démarrage la valeur de la variable root est fixée à partir de celle de la valeur prefix.
En fait la variable prefix indique à grub où se trouvent les modules et les fichiers images (*.img) dont il a besoin pour fonctionner: dans le dossier grub de la partition 1 de la clef usb (qui est considérée comme hd0 puisqu'on a booté dessus).
Puisque search a bien fonctionné, la raison de l'échec du lancement du système linux est a chercher ailleurs: le VBR désigné par la commande chainloader ne contient pas de grub, ou celui-ci est inopérant.
Sans doute grub n'a-t-il jamais été installé sur ce VBR?

La commande multiboot.
Mais pas de problèmes: il n'est pas nécessaire de procéder à cette installation. Pour charger le grub du système linux que nous souhaitons démarrer, il suffit de saisir dans notre shell grub les commandes:
grub> multiboot /grub/i386-pc/core.img 
grub> boot
Ceci implique bien sûr que le label Ubuntu désigne une partition qui sera montée en /boot.
Si Ubuntu désigne la partition racine et qu'aucune partition n'est montée en /boot les commandes à saisir sont:
grub> multiboot /boot/grub/i386-pc/core.img 
grub> boot
Dans les deux cas, le chemin vers core.img n'est pas nécessairement celui indiqué ici. Mais comme la complétion fonctionne très bien, il est aisé de vérifier si on est sur la bonne voie où pas.
Une autre possibilité si cela se passe mal dès le départ est que l'on soit finalement renvoyé vers le chargeur principal. Mais normalement si nous utilisons la clef de secours c'est justement parce que le chargeur principal ne nous permet plus d'amorcer notre système linux. Le désastre étant provoqué par la commande boot figurant dans le grub.cfg de la clef, nous la supprimons avant une nouvelle tentative. Nous atterrissons cette fois dans un shell grub.
L'output de la commande set donne:
prefix=(hd0,msdos1)/grub 
root=hd0,msdos0
La variable root est restée inchangée! La commande search n'a rien donné: aucune partition trouvée avec le label indiqué (Ubuntu dans notre exemple). Il importe avant de poursuivre de donner à la variable root la valeur qui convient, soit directement, par exemple:
grub> set root=(hd1,3)
soit en lançant une nouvelle commande search adaptée.
Évidemment pour savoir quelle est la valeur à attribuer à root, il faut avoir un minimum de connaissance sur la structure du système linux que l'on veut amorcer: quelles sont les partitions utilisées?
Si nous fixons nous-même directement la valeur de root, il peut être utile de vérifier que nous sommes au bon endroit  à l'aide de la commande
grub> ls /
Ici nous vérifions que nous sommes bien sur la partition /boot d'un système Fedora 17 avant de saisir les commandes permettant de charger le grub de ce système:


Si la commande ls / retourne des choses du genre etc/ boot/ home/ ..., cela signifie que nous sommes sur la partition racine d'un système.
Il convient alors d'exécuter la commande ls /boot. Si cette dernière commande ne retourne rien, cela signifie que notre système fonctionne avec en plus de la partition racine, une partition à monter en /boot.

Notons que l'emploi de la commande multiboot n'est pas réservé à une utilisation dans un shell grub: elle peut aussi être utilisée dans un fichier grub.cfg.

La commande configfile.
Une alternative à la commande multiboot est l'utilisation de la commande configfile:
grub> configfile /grub/grub.cfg
Cette commande provoque l'affichage du même menu que celui obtenu avec la commande multiboot. La différence est que cette fois le grub du système linux (dont les fichiers img et mod se trouvent sur le disque dur) n'est pas chargé. On reste dans le même grub (celui de la clef), mais on lui demande d'utiliser le fichier de configuration dont le nom absolu est (hd1,3)/boot/grub (si la variable root vaut hd1,3)

Amorçage en ligne de commande.
Supposons maintenant que notre système linux ne comprenne aucun chargeur où que celui-ci est inopérant.
Impossible d'utiliser la commande multiboot (ou configfile).
Mais rien n'est perdu.
Quelques commandes tapées dans notre shell grub (où placées dans le grub.cfg) suffisent à amorcer le système:

grub> set root=(hd1,3) 
grub> linux /vmlinuz-3.5.0-17-generic root=LABEL=u-root ro
grub> initrd /initrd-3.5.0-generic 
grub> boot

Il est important de ne pas confondre la variable root de la ligne 1 qui se rapporte à la partition où se trouve le noyau (ici vmlinuz-3.5.0-17-generic) avec l'option root de la commande linux qui indique au noyau quelle est la partition racine.
Notons que grâce à la complétion il n'est pas nécessaire de connaître de connaître le nom exact des fichiers vmlinuz et initrd.
Il est cependant utile de connaître le label de la partition racine.
Rappelons que la commande blkid exécutée en root (par exemple depuis un live CD)  fournit tous les renseignements nécessaires.
Signalons enfin que si aucune partition n'est à monter dans /boot, la variable root désigne alors la partition racine puisque c'est elle qui contient le noyau. Mais malgré tout il faut encore indiquer au noyau quelle est la partition racine.
Dans ce cas les commandes à saisir seraient par exemple:

grub> set root=(hd1,3)
grub> linux /boot/vmlinuz-3.5.0-17-generic root=LABEL=Ubuntu ro
grub> initrd /boot/initrd-3.5.0-generic
grub> boot

mardi 1 juin 2010

Stockage CHS

Décodage stockage CHS

Dans le billet précédent, nous avons avec la commande od affiché une table de partitions et nous en avons expliqué le contenu, mis à part certaines zones qui ont été ignorées. Il s'agit des zones où  sont enregistrées les données CHS (Cylindre,Tête, Secteur) relatives au début et à la fin des partitions.
Nous allons expliquer comment décoder les données CHS que l'on peut trouver dans une table de partitions.
Affichons avec od la table de partitions du disque utilisé comme exemple:
# od -Ad -tx1 -j 446 -N 66 /dev/sda
0000446 00 01 01 00 0b ef bf 5e 3f 00 00 00 b1 0a 8c 00 
0000462 80 01 81 5f 07 ef ff ff 2f 0b 8c 00 d1 47 1c 04 
0000478 00 ef ff ff 83 ef ff ff 00 53 a8 04 10 3b 00 00 
0000494 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000510 55 aa 
La colonne 1 de la table nous indique que la partition sda2 est marquée comme étant amorçable.
La colonne 5 nous apprend que:
sda 1 est une partition FAT 32
sda2 est une partition NTFS
sda3 est une partition linux
(Voir billet précédent).
Le secteur qui contient cette table de partition est le secteur 0 du disque: il se trouve sur le cylindre 0 et est lu par la tête 0. Cependant dans le système d'adressage CHS, les secteurs sont comptés à partir de 1.
Son adresse CHS est donc
CHS=(0,0,1)
Pour les autres adresses CHS, nous allons maintenant considérer les colonnes sur fond orange (données CHS du début de la partition) et sur fond gris (données CHS de fin de la partition).
Le premier octet se rapporte à la tête, les deux suivant à l'ensemble secteur cylindre.
Ainsi pour le début de la partition 1, il semble évident que:
CHS=(0,1,1)
Ce n'est pas faux, mais en fait, c'est un peu plus compliqué que cela.
En effet si le premier octet donne le numéro de la tête,  dans le deuxième octet, seuls les bits 0 à 5 correspondent au  numéro du secteur. Les bits 6 et 7  constituent les bits supérieurs (8 et 9) du numéro de cylindre. Le numéro de cylindre est donc un nombre à 10 bits dont le maximum est 1023.
Le tableau suivant montre ce qu'il en est pour le stockage des données relatives à la fin de la partition sda1:

Tête
Secteur Cylindre
E
F
B
F
5
E
1
1
1
0
1
1
1
1
1
0
1
1
1
1
1
1
0
1
0
1
1
1
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
La ligne 2 du tableau reprend les données en hexadécimal provenant de la table de partitions, la ligne 3 reprend les mêmes données en binaire. En ligne 4, on trouve la numérotation des bits.
Les bits sur fond jaune se rapport au numéro de cylindre, les bits sur fond vert au numéro de secteur.
Réorganisons le tableau de manière à mettre ensemble les bits qui constituent le numéro de cylindre:

Tête
Secteur
Cylindre
E
F
3
F
2
5
E
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
0
0
1
0
1
1
1

0
7
6
5
4
3
2
1
0
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
239
63
606
(On a ajouté au tableau une 5ième ligne qui donne l'équivalent en décimal des nombres hexadécimaux de même couleur).
L'adresse CHS de la fin de la partition est donc:
CHS=(606,239,63)
Dessinons des tableaux du même genre pour rechercher l'adresse CHS du début de sda2:

Tête
Secteur Cylindre
0
1
8
1
5
F
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
0
1
0
1
1
1
1
1
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0

Tête
Secteur
Cylindre
0
1
0
1
2
5
F
0
0
0
0
0
0
0
1
0
0
0
0
0
1
1
0
0
1
0
1
1
1
1
1
7
6
5
4
3
2
1
0
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
1
1
607
On trouve:
CHS=(607,1,1)
Les autres données CHS qui figurent dans la table de partition étudiée sont toutes égales à EF FF FF FF ce qui donne des numéros de cylindre valant tous 3FF (1023). Ces données ne sont donc d'aucune utilité pour établir des adresses CHS.
Cependant, il existe des formules permettant de calculer l'adresse CHS à partir du système d'adressage LBA (Logical Block Adress) dans lequel les N blocs logiques d'un disque sont numérotés de 0 à N1. Les blocs logiques sont ici identiques aux secteurs et l'adresse LBA du début des partitions est celle qui figure dans la table de partitions occupant les colonnes 9 à 12. Pour l'adresse de fin, il suffit d'ajouter la taille (en secteurs) moins 1. Si A désigne l'adresse LBA, NS le nombre de secteurs par piste et NT le nombre de têtes, les formules sont les suivantes:
S = ( A % NS ) + 1
H = ( A - S + 1 ) / NS % NT
C = ( A - S + 1 ) / NS / NT
(% est l'opérateur modulo)
Pour notre disque exemple NS=63 et NT=240
Calculons l'adresse CHS de la fin de la partition sda1, pour vérifier si on retrouve bien les valeurs directement lues dans la table des partitions.
Rappelons que les adresses en secteurs (en blocs logiques) des partitions se présentent dans la table de partitions sous forme d'un nombre hexadécimal de 32 bits au format little-endian. Idem pour les tailles qui elles se trouvent aux colonnes 13 à 16. On pourrait convertir ces adresses et ces tailles en nombre décimal, ou même les afficher directement sous ce format à l'aide de od (voir billet précédent), mais la puissance extraordinaire de la ligne de commande linux fait qu'il n'est même pas nécessaire d'effectuer ces conversions:
$ A=$((0x3f+0x8c0ab1-1))
$ S=$(((A%NS)+1))
$ H=$(((A-S+1)/NS%NT))
$ C=$(((A-S+1)/NS/NT))
$ echo $C,$H,$S
606,239,63
Procédons de même pour la fin de la partition sda2:
A=$((0x8c0b2f+0x41c47d1-1))
$ S=$(((A%NS)+1))
$ H=$(((A-S+1)/NS%NT))
$ C=$(((A-S+1)/NS/NT))
$ echo $C,$H,$S
5167,239,63
Ces dernières valeurs ne peuvent pas être stockées dans la tables de partitions à l'emplacement prévu, puisque le numéro du cylindre est supérieur à 1023.