In this post I'm going to discuss the UEFI and BIOS firmware standards.

In questo post discuterò degli standard per i firmware UEFI e BIOS.

Dissertation on UEFI and BIOS

After the Introduction of "MSI the Rhetor" to my arsenal, I had to face a problem that is now very common, and I'm sure, many of you already faced, that is, the installation of operating systems on computers using the UEFI standard.

Even though my problem was related to the installation of operating systems, in this post, I intend to deal with the historical BIOS standard and the current UEFI standard, in their entirety.
In particular, I will talk about:

  • the computer's (VEEERY simplified) boot process;
  • the characteristics of the BIOS firmware;
  • the characteristics of the UEFI firmware;
  • some considerations related to the [re]installation of the GRUB boot manager, due to the differences between the two types of firmware;

Ok, let's begin.

The unknown powering process

Even though propaganda teaches us that technology has become "smart", the reality is that computers (and derived machines) are "stupid".
The sense of this phrase is: "Computers perform only what it is told them to", ergo, "Computers do not perform anything until it is told them to".

Even during the powering process, the sentence is still valid, therefore, it is necessary to instruct the computer, for it to "power on correctly".
Mother boards are equipped with a memory which has the purpose of keeping the instructions the computer will use to "power on" (technically, it is said "to perform the boot sequence", or simply, "to boot up").

Those instructions, in other words, that program, is defined as "firmware", the name is due to it residing in this particular memory.
In the past, these memories were read only and thus, not upgradable in time.
This is why the term "firm" was used, because the program couldn't be upgraded, it was "firm".

Of course, the above description is very simplistic, in fact, these firmwares' purpose is not only to "power" the components, they provide other functionalities too, like the diagnostics, the management of the components themselves and the application of user defined settings at firmware level.
A particular menu, which is accessible by pressing a certain key during the machine boot up, can be used to change those settings.
Thanks to this menu, it is possible to change the settings related to the hardware (for example, enabling/disabling ports, power consumption management) and those related to the firmware (time, boot order...) and many others.
All these settings are kept in another small memory on the mother board, the NVRAM (Non volatile RAM), powered by a button battery.

To simplify, the firmware's purpose is to, through a sequence of steps, allow the computer to power up, find the components on the mother board, initialize them, apply the user defined settings, perform a verification to establish that the components work and in the end, read the hard disk, to find operating systems to boot.

At this point you might ask, what do initials like UEFI and BIOS, have to do with the things we have discussed about until now.
These are standards for mother boards' firmwares, that is, they dictate the functionalities the firmware must guarantee, in respect to the used standard.
In other words, when a mother boards' producer will start develop the firmware of the board, he must guarantee that the firmware will provide the functionalities reported by the chosen standard.

The historical BIOS

The BIOS standard (Basic Input Output System), was used to develop mother boards' firmwares until 2011.
It was developed for the first time on IBM PCs, with the purpose of providing basic functionalities like keyboard and screen management, so that operating systems would have used BIOS to request those services.

In the following years though, it was noted that the use of BIOS services to access the underlying hardware, brought execution slowness (this was particularly true for graphical operations), in fact, in recent computers, BIOS is not used this way anymore.
Today, hardware access through BIOS is used exclusively during boot up and when the firmware settings menu is used.
Operating systems access hardware directly, through the use of programs called drivers, written for the purpose.

Since this standard was born on IBM PCs, it is usable only on mother boards which support the x86 family of processors.
This limitation is due to BIOS executing code in "real mode".

Real mode, is an execution mode available in this processors' family since the 8086 processor.
Programs who run in this mode can address (that is, they can refer to) a maximum of 1 Mebibytes of memory (an address is represented with 20 bits, ergo 2^20 bytes).
Moreover, they have indiscriminate access to the computer's memory, although limited in recent computers, due to the reduced address space.
This indiscriminate access is possible because, in this mode, there's no concept of protected memory, in which the program can access only the memory block assigned to it by the operating system.

The protected mode was introduced with the 80286 processor.
This mode added further memory management techniques, such as virtual memory, paging and multitasking (with consequent protected memory).
Even though x86 processors are executed in protected mode nowadays, computers with BIOS firmware execute code in real mode, at boot up and in general, when the firmware is used.

Reading of the hard disk according to BIOS

When it is time to read the hard disk, the BIOS firmware instructs the computer to read the first sector of the disk, in it, a program called "boot loader" will be found.
Once the computer loads the program, it will analyze the rest of the disk, in order to search for bootable operating systems.
When one is found, the computer boots it.

BIOS: the MBR partitioning scheme

The BIOS firmware allows to recognize disks partitioned with the MBR scheme.
In the GParted program, this partitioning scheme is called "ms-dos".

In reality, MBR is an acronym for "Master Boot Record", that is, the first sector of the hard disk mentioned previously.
First of all, it is called "Master", simply because it is the first sector read by the computer, secondly, because the partitioning scheme stores in it, all the useful information used to recognize the partitions.
A MBR is structured this way:

  • In the first 446 bytes is stored a program called boot loader.
    As already mentioned, it allows the execution of operating systems.
  • In the next 64 bytes is stored the partition table.
  • The last two bytes contain the magic numbers "55" "AA".
    In reality, this is the two bytes value "AA55" stored in Little Endian, here reported in hexadecimal (base 16).
    Please note, two digits of that numerical base correspond to a single byte.
    That value at the end of the sector, indicates the "end" of the MBR.

As already written, the last two bytes are reserved for the value "AA55" stored in Little Endian.
"Endianess" of a processor is defined as the sequential order used to store data, in particular, those that require MORE than a single byte to be represented, since a single byte value, by definition, is already ordered.
It is distinguished in:

  • Big Endian: FIRST the MOST SIGNIFICANT bytes are stored, THEN the LEAST SIGNIFICANT ones are.
    For example, the four bytes value "FFAA4522", is stored as "FF" "AA" "45" "22".
    Please note, this is the "natural" method we use to write numbers.
  • Little Endian: FIRST the LEAST SIGNIFICANT bytes are stored, THEN the MOST SIGNIFICANT ones are.
    For example, the four bytes value "123400FF", is stored as "FF" "00" "34" "12".

The x86 family of processors stores (and operates with) data using the Little Endian sequential order.

I want to make you notice it was assumed a sector's size was 512 bytes, this is true for IBM PCs and compatible ones, but not in general though.
Please also notice, the simpler boot loaders instruct the computer to scan the partition table, in order to search for a bootable partition (that is, one which has the so called "boot flag").
When the partition is found, the operating system contained in it is booted.
On the contrary, boot loaders such as GRUB, LILO and others, have become too complex to be contained in 446 bytes.
In these cases, the instructions contained in that section have the purpose to load the actual boot loader, which is elsewhere in the disk, then, that program will look for its configuration files (for example, for GRUB it is grub.cfg), which will allow to boot the desired operating system.

Moreover, the MBR scheme establishes that a hard disk can contain a maximum of four partitions, and each one can't occupy more than 2 TiB (Tebibyte).

The 2 TiB limit is because in the partition table are used 32 bits (4 bytes) values to refer to sectors, in particular, the initial sector of a partition and the number of sectors it contains.
As a consequence, knowing that a sector's size is 512 bytes, and knowing that disk sectors can be referenced using 32 bits "addresses", we have 2^32 "addressable" sectors, and a required space of 512 * (2^32) = 2 TiB per partition.
Of course, the limit changes if the sector's size changes.

Initially, the four partitions were not a big deal, but in following years they started being a limitation, which brought the need to improve the scheme, introducing the possibility to specify the type of partition.
The partitions in the modern MBR are divided into:

  • Primary: "Simple" partition
  • Extended:
    Partition which contains other partitions.
    This information is reported in the partition table.
  • Logical:
    Partition contained within an extended partition.
    The information of a single partition is stored in its first sector, defined as EBR (Extended Boot Record).
    In that sector, are stored data such as the size of the partition and the position in the disk of the next logical partition.
    As you can see, these EBRs arrange a linked list, the access to these partitions is sequential.

Inside the extended partition, it is theoretically possible to have an infinite number of logical partitions.
In reality, operating systems recognize only a limited number of those.

Unfortunately, MBR can have only ONE extended partition.
In other words, a configuration which takes advantage of the entire hard disk, can only be of two types:

  • Four primary partitions;
  • Three primary partitions and an extended one;

Furthermore, an extended partition has the same limits of a primary one, that is, a maximum of 2 TiB of space.
To be fair though, the 2 TiB limitation has not represented a problem until a decade ago, with the advent of hard disks with sizes in Terabyte.

UEFI's arrival

UEFI (Unified Extensible Firmware Interface) is a modern standard for mother boards' firmware.
The development of this standard started in the mid-nineties with the name "EFI" (without "Unified"), it was thought to be used on machines which mounted the first processor (at the time, still in development) of the Itanium family (IA 64).
That processor, in spite of being initially developed by HP, was then built in partnership with Intel.
On the contrary, the EFI specs were developed by Intel only.

Intel continued developing those specs until version 1.10.
In 2005, an organization composed by many (important) companies which work in the technology field (other than Intel itself, AMD, ARM and American MegaTrends just to name a few), the "Unified EFI Forum", was founded.
Its purpose was to define a new standard for firmware's development, in order to replace the old BIOS.
As the organization's name suggests, Intel's EFI specs were used as a base, with them, it was created what we know today as UEFI.
To this day, UEFI specs are still updated and improved.

Among UEFI's characteristics, there is the independence from the particular processor's architecture (contrary to BIOS, which supports the x86 family only), there are the drivers, written for the purpose, that allow UEFI to manage the machine in its entirety, there is also a compatibility module called CSM (Compatibility Support Module), that allows the UEFI firmware to emulate the behaviour of a BIOS firmware, this way, operating systems which do not support the new standard can still be used.
Not all UEFI firmwares have this module though, furthermore, Intel recently stated that it would stop providing CSM starting from 2020.
Anyway, this type of firmware can be compared to a mini operating system in which its "main" part resides on the mother board.

UEFI has been designed to be extensible:
The standard provides an execution environment that can load files with the "efi" extension, which are executable programs.
It's thanks to these if it is possible to boot operating systems in the UEFI standard, in fact most of them, when run, behave like boot loaders.

It is also possible to write our own efi programs (I refer you to this guide, if you want to have a try).
Often, an efi shell is also available (it is accessible from the firmware's settings menu), with it, it is possible to perform maintenance operations, like file management on hard disk, mass storages and optical disks, it is possible to connect to the Internet and above all, it is possible to execute efi programs and scripts.

As already stated before, during the boot process, the BIOS firmware instructs the computer to execute code in real mode, also known as "16 bits" code, because 8086 was a 16 bits (equivalent to 2 bytes) processor.

It is said that a processor is XX bits, when the "native" type of data (that is, the one the processor considers as a "unit", technically called "word" of the processor) is represented using XX bits.
Usually, this implies that the data bus (the communication channel that allows data exchange between components), the address bus (the bus used by the processor to establish where to read from/write to) and the processor's registers have size equal to XX bits, this is not always true however.
By extension, it is said that a computer is XX bits, if it mounts a XX bits processor.

I want to make you notice that processors of the x86 family, are backward compatible with processors of the same family which have a smaller word.
For example, 64 bits (equivalent to 8 bytes) x86 processors can execute code thought for 32 bits x86 processors and previous ones, which in turn can execute code thought for 16 bits processors and previous ones, and so on.

Even though it may be banal at this point, it is important to note that in order for a program (or operating system, since it is still a program), "to take advantage of the XX bits" of the processor, it is necessary to compile it for that kind of processor.
Therefore, in that program, the word's size will be considered equal to XX bits.
Even here, by extension, it is said that a program or operating system is XX bits.

While BIOS, at boot up, can use code used on 8086 AT MOST, therefore VERY LIMITED even in relation to registers' access (just think that during this phase, a 32 bits processor, can execute code which operates at most on the first 16 bits of each register), UEFI on the other hand, allows the execution of code according to the effective word of the processor.
The UEFI standard establishes that a mother board's firmware, can be compiled for execution on 32 bits processors (in this case we talk about 32 bits UEFI), or for execution on 64 bits processors (in this other one, 64 bits UEFI).

There's one last thing to add about the BIOS firmware.
If a computer with that type of firmware had a 64 bits processor, it didn't matter what system was installed, since the computer would execute code in real mode, and then in protected mode, when the operating system was booted.
Being the x86 family backward compatible, you could have a 64 bits processor, with a 32 bits operating system (of course, you couldn't do the opposite).

Unfortunately, UEFI doesn't reason the same way, in fact, it is not possible to execute efi programs compiled for 32 bits UEFI, on 64 bits UEFI.
With this standard, only efi programs compiled for the firmware IN USE can be executed, so, a 32 bits efi program implies 32 bits UEFI, a 64 bits efi program implies 64 bits UEFI.
While this, theoretically, shouldn't bring limitations in relation to installable operating systems (since this limit is related to the efi executables), in practice, it is necessary that the executed operating system kernel, has the same word of the UEFI firmware in use.
As a consequence, IT IS NOT POSSIBLE to install 32 bits systems on 64 bits UEFI and viceversa.
The only exception to this rule seems to be the Linux kernel, thanks in fact to the "mixed mode" of some boot loaders used on that platform, it seems possible to boot a 64 bits Linux kernel, from a 32 bits UEFI firmware.

Reading of the hard disk according to UEFI

Contrary to BIOS, UEFI doesn't use the Master Boot Record (that is, the first sector) to establish what operating system to boot.
The standard expects to find at the start of the disk, a partition of arbitrary size (usually equal or greater than 512 Mebibytes) and formatted with a file system compatible with the FAT standard (usually fat32 or fat16).
This partition is called ESP (EFI System Partition), its purpose is to contain all the efi programs which will be executed in the UEFI environment.

During boot up, when it is time to read the disk, the UEFI firmware instructs the computer to check the content of some variables residing in the mother board's NVRAM (we said earlier that this memory stores all the settings used by firmwares).
Those variables refer to the efi programs contained in the ESP, all of them define a boot order (editable from the firmware settings), in other words, they establish the order in which the efi programs will be executed.
In the simpler case, those programs are nothing more than operating system boot loaders.
According to this order, the computer will try to execute the first efi program it finds in the ESP partition.
If an efi program referenced by a certain variable is not found, the next variable is read.
This way, it is possible to boot operating systems.

UEFI: the GPT partitioning scheme

Before starting talking about the GPT partitioning scheme, a foreword regarding UEFI's supported schemes is due.

Although MBR has many limitations on a modern system, the UEFI standard imposes complete compatibility with it, provided that, there exists at the start of the disk, a partition which acts as an ESP.
As a consequence, it should be possible to execute operating systems natively, even using this scheme.

Unfortunately, in practice, this is not always true:
First of all, there are implementations of the UEFI standard that, when a MBR hard disk is found, they enable the CSM (the compatibility module discussed earlier).
Secondly, there are operating systems' installers (such as the Windows ones), that even if correctly booted in UEFI mode, when a MBR hard disk is found, they prevent the installation of the system, declaring that in order to continue, it is necessary to format the entire disk using the GPT scheme.
The two above mentioned cases, are examples of standard's violation.

Said this, the UEFI standard prefers the GPT (GUID Partition Table) partitioning scheme.
The name is due to GPT using GUIDs (Globally Unique Identifier) to refer to the single partitions.
In general, GUIDs (or UUIDs, Universally instead of Globally) are 128 bits (equivalent to 16 bytes) values used to identify any software entity, in this case, the single partitions.
It was calculated that the probability that two different entities are identified using the same GUID is close to 0.
This allows to assert that every entity can be referenced uniquely using a GUID.

This partition scheme allows a maximum size of 8 ZiB (Zebibyte) per partition, assuming again, that a sector's size is 512 bytes.
The reason for this number is the following: Contrary to MBR, GPT uses 64 bits values to reference sectors, therefore, there are 2^64 addressable sectors, for a total of 512 * (2^64) = 8 ZiB of required space.
To get an idea, 1 Zebibytes = 2^30 Tebibytes = 2^70 bytes, in other words, a maximum space of 8 billions Terabytes (a bit greater in reality, being them Tebibytes).
Again, different sector's size implies a different limit.

A disk partitioned with GPT has the following structure:

  • The sector 0 (the first) is defined as "protective MBR".
    It is an actual Master Boot Record, however, its purpose is to avoid that operating systems which DO NOT support UEFI and GPT, may apply modifications on the disk.
    If a computer with BIOS firmware reads this MBR, it will recognize the disk as a single partition with an unknown file system and many programs that manage disks, will prevent disk editing.
  • The sector 1 (the second) is defined as "Partition Table Header".
    In here, all the disk information is reported, for example:
    • The number of existing partitions;
    • In which sector is located the start of the first partition;
    • The UUID which represents the disk itself;
  • Partition table (from sector 2 to sector 33 included, that is, from the third to the thirty-fourth):
    In here, is stored all the information related to the single partitions.
    Examples of information are:
    • The partition's UUIDs:
      • Type UUID:
        That is, the UUID which identifies the purpose of the partition.
        This UUID is equal for all the partitions of the same type.
        For example, all the ESP partitions have the Type UUID set to the value "C12A7328-F81F-11D2-BA4B-00A0C93EC93B".
      • Identification UUID:
        That is, the UUID which identifies the partition itself, regardless of its purpose.
        This way, it is possible to distinguish it from the other ones on the disk.
    • Where the partition is located in the disk.
  • The effective partitions:
    Teoretically, it is possible to have an "infinite" number of partitions, however, even here, as already discussed in the "extended partition" section of the MBR scheme, operating systems will recognize a limited number of partitions.
  • A copy of the sectors 1, 2 up to 33.
    It is said that GPT is a "redundant" scheme, in the sense that it writes the same information reported before, even at the end of the disk.
    This is done so that the data can be easily recovered in case of problems.

Some considerations on GRUB

As already written at the beginning of the post, my main problem was related to the installation of operating systems and consequent boot manager, in particular, Debian with the GRUB boot manager.

According to what has been discussed, the method to install operating systems and allow them to boot, changes dramatically between the two standards, it is therefore necessary to know what to do, in order to avoid making the computer unusuable.

BIOS firmware

On this type of firmware, GRUB needed to be installed (in the majority of cases) on the Master Boot Record.
Usually, to simplify the creation of "multiboot" systems (that is, with multiple operating systems), there was the convention to FIRST install Windows and THEN anything else.
The reason was due to Windows replacing the boot loader in the Master Boot Record at every installation, as a consequence, people could boot only Windows, despite having other systems installed.

Unfortunately, unexperienced people used to make the mistake of installing GNU/Linux (or whatever it was) FIRST and THEN Windows.
In the case of GNU/Linux with the boot manager GRUB, it was possible to solve this problem using an external live distribution (for example the GParted Live CD) and start a chroot session of the installed GNU/Linux system.
Finally, reinstall GRUB with a command like the one below:

grub-install <HD_DEV> --boot-directory=<BOOT_DIR>

where HD_DEV is the block device representing the hard disk and BOOT_DIR is the directory where the "boot" partition, used to store the boot files, like the kernels and GRUB's configuration file, is mounted (in simple systems, it corresponds to the "/boot" directory of the GNU/Linux partition).

After a reboot, it was possible to boot AGAIN into GNU/Linux, because the boot loader was overwritten.

UEFI firmware

On the contrary, on UEFI firmwares, it is not strictly necessary to reinstall GRUB.

As we already said, the efi programs allow to boot operating systems in UEFI firmwares, furthermore, the UEFI environemnt uses the boot order stored in NVRAM.
Operating systems' installers tend to set the first variable related to the boot order, other than placing their efi programs on the ESP partition.
As a consequence, after rebooting, the operating system they installed will be the first to be booted.

As you may guess, in normal situations it doesn't matter which operating system is installed first, because if needed, the firmware allows the user to edit the entries related to the boot order.
Therefore, if GNU/Linux was installed first, then Windows, the latter one will be the first to be booted.
To solve, we just need to edit the boot order entries and set the first variable to GNU/Linux.
If the firmware's menu does not allow that, it is possible to use the efi shell, if this is not possible too, then you have to use a disk like GParted Live CD, however, you need this only if the settings menu is extremely limited.

It is needed to reinstall GRUB when, for example, its efi files are deleted by accident, or they are corrupted.
Again, you need an external disk booted in UEFI mode (why not, even the GParted Live CD), then you need to perform the chroot session, but this time, you need to mount the ESP partition TOO, and finally, reinstall by using a command like this:

grub-install <HD_DEV> --boot-directory=<BOOT_DIR> --efi-directory=<EFI_DIR>

where HD_DEV is the block device representing the hard disk, BOOT_DIR is the directory where the boot partition discussed earlier is mounted and finally, EFI_DIR, is the directory where the ESP partition is mounted.


In conclusion, today, we have discussed about the two standards related to the firmware and how UEFI outclassed BIOS in almost all fronts.
Modern computers mount UEFI and soon enough, the compatibility with the old firmware will be removed.
As with everything which was used for a long time, BIOS has made history.

Well, I hope you liked this post and that you find it useful at informative level.
Greetings from Antonio Daniele.
See you next time.

Go back to the top, Share, Look at the comments or Comment yourself!

Dissertazione su UEFI e BIOS

In seguito all'introduzione di "MSI Il Retore" nel mio arsenale, ho dovuto affrontare una problematica ormai piuttosto comune, e che, sono sicuro, molti di voi ha già affrontato, ovvero, l'installazione di sistemi operativi su calcolatori con standard UEFI.

Sebbene il mio problema fosse inerente l'installazione di sistemi operativi, in questo post ho intenzione di trattare dello storico standard BIOS e dell'attuale standard UEFI, nella loro interezza.
In particolare, parlerò:

  • della fase d'avvio (MOOOLTO semplificata) di un calcolatore;
  • delle caratteristiche dei firmware BIOS;
  • delle caratteristiche dei firmware UEFI;
  • di alcune considerazioni inerenti la [re]installazione del boot manager GRUB, dovute alle differenze tra i due tipi di firmware;

Bene, iniziamo il post.

L'accensione, questa sconosciuta

Tutti sanno che, per quanto si propagandi che la tecnologia sia diventata "smart" (perché usare l'italiano "intelligente" è diventato opzionale), i computer (e derivati) sono "stupidi".
Il senso di questa frase è il seguente: "I computer fanno solo ciò che gli viene ordinato", ergo "I computer non fanno alcunché finché non gli viene ordinato".

Anche durante l'accensione vale la frase precedente, pertanto è necessario istruire il computer affinchè "si accenda correttamente".
Le schede madri vengono equipaggiate con una memoria, che ha lo scopo di mantenere al suo interno le istruzioni che il computer utilizzerà per "accendersi" (a livello tecnico si dice "per eseguire la sequenza di boot").

Tali istruzioni, e dunque tale programma, viene definito "firmware", così chiamato perché risiede su questa memoria.
Contrariamente ad oggi, tali memorie in passato erano in sola lettura, ovvero non aggiornabili nel tempo, per questo venne usato il termine "firm" per indicare che tale software, non avrebbe subito modifiche, sarebbe appunto rimasto "stabile", "fermo".

Ovviamente, la descrizione qui data è molto semplicistica, infatti questi firmware non hanno solo lo scopo banale di "accendere" i componenti, hanno anche altre funzioni come la diagnostica, la gestione stessa dei componenti e l'applicazione di eventuali opzioni scelte dall'utente, sempre in ambito firmware.
Per cambiare tali impostazioni, si usa un menù particolare accessibile premendo un certo tasto all'avvio della macchina.
Grazie a questo menù, è possibile cambiare le impostazioni inerenti l'hardware (ad esempio, [dis]abilitazione di porte, gestione dell'alimentazione), quelle inerenti il firmware (orario, ordine d'avvio...), ed altre ancora.
Tutte queste impostazioni, vengono memorizzate in un'altra piccola memoria presente sulla scheda madre, la NVRAM (Non Volatile RAM), alimentata da una batteria a bottone.

Detto semplicemente, il firmware ha lo scopo, attraverso tutta una sequenza di fasi, di permettere al computer di accendersi, di scovare i componenti montati sulla scheda madre, di inizializzarli, applicare le opzioni richieste, eseguire le operazioni di verifica del funzionamento degli stessi, e solo alla fine, procedere alla lettura del disco fisso, per trovare ed eseguire eventuali sistemi operativi.

A questo punto potreste chiedervi cosa centrano le sigle UEFI e BIOS, con ciò di cui abbiamo discusso finora.
Questi sono due standard per il firmware della scheda madre, ovvero, dettano quali funzionalità il firmware deve garantire rispetto allo standard utilizzato.
In altri termini, un produttore di schede madri, quando andrà a sviluppare il firmware della scheda, dovrà garantire che tale firmware avrà le funzionalità riportate dallo standard scelto.

Lo storico BIOS

Lo standard BIOS (Basic Input Output System), è stato utilizzato per sviluppare il firmware delle schede madri fino al 2011.
Venne sviluppato per la prima volta sui PC IBM, con lo scopo di fornire funzionalità di base come la gestione della tastiera e dello schermo, in maniera tale che i sistemi operativi si interfacciassero a BIOS, per richiedere tali servizi.

In seguito tuttavia, si notò che l'utilizzo dei servizi di BIOS per accedere all'hardware sottostante, portava ad una lentezza d'esecuzione (questo era particolarmente vero per le operazioni grafiche), ed infatti, nei computer recenti, BIOS non viene più usato così.
Oggi, l'accesso all'hardware tramite BIOS viene usato esclusivamente durante la fase d'avvio e anche quando si accede al menù delle impostazioni del firmware.
I sistemi operativi invece accedono all'hardware in maniera diretta, attraverso programmi detti driver, scritti apposta per essi.

Essendo questo standard nato sui PC IBM, esso è utilizzabile solo su schede madri che prevedono processori con architettura x86.
Questa limitazione è dovuta al fatto che BIOS esegue codice in "modalità reale".

La modalità reale è una modalità d'esecuzione presente nei processori di questa famiglia fin dall'8086.
I programmi che girano in questa modalità possono indirizzare (cioè far riferimento ad) un massimo di 1 Mebibyte di memoria (un indirizzo è rappresentato da 20 bit, ergo 2^20 byte).
Essi inoltre hanno accesso indiscriminato alla memoria dell'elaboratore, seppur limitato nei computer più recenti, visto lo spazio di indirizzamento ridotto.
L'accesso indiscriminato è dovuto alla non esistenza, in tale modalità, del concetto di memoria protetta, secondo cui un programma può accedere solo al blocco di memoria assegnatoli dal sistema operativo.

Dall'80286 venne introdotta la modalità protetta che aggiungeva ulteriori tecniche di gestione della memoria, come la memoria virtuale, la paginazione e il multiprocesso (conosciuto dai più come "multitasking", con conseguente memoria protetta).
Sebbene oggi i processori x86 vengono eseguiti per lo più in modalità protetta, nei computer con firmware BIOS, all'avvio e in genere, quando si utilizza il firmware, viene eseguito codice in modalità reale.

Lettura del disco fisso secondo BIOS

Alla lettura del disco fisso, il firmware BIOS istruisce il computer a leggere il primo settore del disco, in esso, verrà trovato un programma detto "boot loader", che una volta caricato, farà analizzare al computer il resto del disco, in cerca di un sistema operativo avviabile.
Una volta trovato, esso viene eseguito.

BIOS: lo schema di partizionamento MBR

Il firmware BIOS permette di riconoscere dischi partizionati con lo schema MBR.
Nel programma GParted, questo schema di partizionamento viene denominato "ms-dos".

In realtà, MBR è un acronimo di "Master Boot Record", cioè del primo settore del disco fisso già menzionato in precedenza.
Viene denominato "Master" (cioè padrone, maestro, principale) innanzitutto perché banalmente, è il primo settore che viene letto dal computer, in secondo luogo, perché lo schema di partizionamento memorizza in tale settore tutte le informazioni utili al riconoscimento delle partizioni.
Un MBR è strutturato in questa maniera:

  • Nei primi 446 byte risiede il programma chiamato boot loader.
    Come già detto, esso si preoccupa di far eseguire i sistemi operativi.
  • Nei successivi 64 byte risiede la tabella delle partizioni.
  • Gli ultimi due byte contengono i numeri magici "55" "AA".
    In realtà si tratta del valore a due byte "AA55" memorizzato in Little Endian, qui riportato in esadecimale (base 16).
    Vi prego di notare che due cifre di tale base numerica corrispondono ad un byte.
    Tale valore alla fine del settore, indica la "fine" del MBR.

Come già scritto, gli ultimi due byte sono riservati al valore "AA55" memorizzato in Little Endian.
Si definisce "Endianess" di un processore, l'ordine sequenziale usato per memorizzare i dati, in particolar modo, quelli che richiedono PIÙ di un byte per essere rappresentati, questo perché un valore di un singolo byte è per definizione già ordinato.
Si distingue in:

  • Big Endian: vengono memorizzati PRIMA i byte PIÙ SIGNIFICATIVI e DOPO i byte MENO SIGNIFICATIVI.
    Ad esempio, il valore "FFAA4522" a quattro byte, viene memorizzato come "FF" "AA" "45" "22".
    Notiamo che è il metodo "naturale" usato da noi per scrivere i numeri.
  • Little Endian: vengono memorizzati PRIMA i byte MENO SIGNIFICATIVI e DOPO i byte PIÙ SIGNIFICATIVI.
    Ad esempio, il valore "123400FF" a quattro byte, viene memorizzato come "FF" "00" "34" "12".

La famiglia di processori x86 memorizza (e opera con) i dati utilizzando l'ordine sequenziale Little Endian.

Faccio notare che qui si è assunto che un settore abbia dimensione 512 byte, questo è vero per i PC IBM e compatibili, ma non è vero in generale.
Faccio notare ulteriormente, che i boot loader più semplici istruiscono il computer a scandire la tabella delle partizioni in cerca di una che sia avviabile (cioè una a cui sia stato impostato il cosidetto "boot flag").
A partizione trovata, si procede all'avvio del sistema operativo contenuto in essa.
Al contrario, boot loader come GRUB, LILO ed altri, sono ormai divenuti troppo complessi per essere contenuti in soli 446 byte.
In questi casi, le istruzioni contenute in quella sezione hanno il solo scopo di caricare l'effettivo boot loader, che si trova da qualche parte sul disco, poi tale programma leggerà eventuali file di configurazione (ad esempio grub.cfg nel caso di GRUB), che permetteranno così di eseguire il sistema operativo desiderato.

Lo schema MBR stabilisce inoltre che un disco fisso può contenere solo un massimo di quattro partizioni, e ognuna di esse può occupare al più 2 TiB (Tebibyte).

Il limite dei 2 TiB è dovuto al fatto che nella tabella delle partizioni vengono usati valori a 32 bit (4 byte) per far riferimento ai settori, in particolare, il settore iniziale di una partizione e il numero di settori che essa contiene.
Conseguenza di ciò, sapendo che un settore ha dimensione 512 byte, e sapendo di poterci riferire ai settori di un disco usando "indirizzi" a 32 bit, avremo 2^32 settori "indirizzabili", e uno spazio richiesto di 512 * (2^32) = 2 TiB a singola partizione.
Ovviamente, il limite cambia se cambia la dimensione del settore.

Inizialmente, le quattro partizioni non erano un grosso problema, ma in seguito cominciò a rappresentare un limite che portò a migliorare lo schema, introducendo la possibilità di specificare il tipo di partizione.
Le partizioni nello schema MBR moderno si dividono in:

  • Primaria: Partizione "semplice"
  • Estesa:
    Partizione che contiene altre partizioni.
    Il fatto che essa sia estesa viene segnalato nella tabella delle partizioni.
  • Logica:
    Partizione contenuta all'interno di una partizione estesa.
    Le informazioni di una singola partizione sono immagazzinate nel primo settore della stessa, definito come EBR (Extended Boot Record).
    In tale settore sono memorizzati dati come la dimensione e la posizione nel disco della partizione logica seguente.
    Come si può constatare, questi EBR formano una lista concatenata, l'accesso alle partizioni è di tipo sequenziale.

All'interno di una partizione estesa dunque, è possibile teoricamente avere un infinito numero di partizioni logiche.
In realtà, i sistemi operativi riconoscono solo un numero limitato di tali partizioni.

Sfortunatamente, MBR prevede l'uso di un'UNICA partizione estesa.
Detto altrimenti, una configurazione che sfrutti l'intero disco fisso può essere solo di due tipi:

  • Quattro partizioni primarie;
  • Tre partizioni primarie e una estesa;

Inoltre, una partizione estesa ha gli stessi limiti di una partizione primaria, cioè 2 TiB al massimo di spazio.
A onor del vero però, il limite dei 2 TiB non ha rappresentato un problema fino ad una decina d'anni fa, con l'avvento dei dischi fissi di taglia dell'ordine dei Terabyte.

L'avvento di UEFI

UEFI (Unified Extensible Firmware Interface) è uno standard moderno per i firmware delle schede madri.
Lo sviluppo di questo standard inizio a metà anni novanta col nome "EFI" (cioè senza "Unified"), ed era pensato per essere utilizzato sulle macchine che avrebbero montato il primo processore (allora ancora in sviluppo) della famiglia Itanium (IA 64).
Tale processore, sebbene sviluppato inizialmente da HP, venne poi costruito in collaborazione con Intel.
Contrariamente, la specifica di EFI venne sviluppata solo da Intel.

Intel continuò a sviluppare tale specifica solo fino alla versione 1.10.
Nel 2005 venne fondata la "Unified EFI Forum", cioè un'organizzazione composta da varie aziende (importanti) che operano nel campo della tecnologia (oltre alla stessa Intel, AMD, ARM e American MegaTrends per citarne alcune), il cui scopo era quello di definire un nuovo standard per lo sviluppo dei firmware, in maniera tale da rimpiazzare il vecchio BIOS.
Come suggerisce il nome dell'organizzazione, essi presero come base la specifica di EFI di Intel, e venne creato così lo standard che oggi conosciamo come UEFI.
Ad oggi la specifica di UEFI continua ad essere aggiornata e migliorata.

Tra le caratteristiche di UEFI abbiamo l'indipendenza dall'architettura del processore (contrariamente a BIOS, che supporta la sola famiglia x86), i driver scritti apposta, che permettono a UEFI di gestire la macchina nella sua interezza, ed anche un modulo di retrocompatiblità chiamato CSM (Compatibility Support Module) che permette al firmware UEFI di emulare il comportamento di un firmware di tipo BIOS, permettendo così l'utilizzo di sistemi operativi che non supportano il nuovo standard.
Non tutti i firmware UEFI però dispongono di questo modulo, ed inoltre, Intel ha recentemente annunciato di voler smettere di fornire CSM a partire dal 2020.
Ad ogni modo, questo tipo di firmware è paragonabile ad un mini sistema operativo la cui parte "principale" risiede sulla scheda madre.

UEFI è pensato per essere estendibile:
Lo standard fornisce un'ambiente di esecuzione che può caricare file con estensione "efi", che sono a tutti gli effetti programmi eseguibili.
È grazie a questi programmi se è possibile eseguire i sistemi operativi con questo standard, infatti molti di questi file, sono eseguibili, che quando avviati si comportano da boot loader.

È persino possibile scrivere dei propri programmi efi, che poi potranno essere eseguiti (vi rimando a questa guida se volete dilettarvi nello sviluppo).
È spesso disponbile anche una shell efi (accessibile dal menù delle impostazioni del firmware), che oltre a permettere operazioni di manutenzione quali la gestione dei file su disco fisso, memorie di massa e dischi ottici, e il collegamento ad Internet, permette anche l'esecuzione diretta di programmi efi e di script.

Come abbiamo già detto in precedenza, il firmware BIOS, durante l'avvio, fa eseguire al computer codice in modalità reale, detto altresì a "16 bit", perché l'8086 era un processore a 16 bit (che equivalgono a 2 byte).

Si dice che un processore è a XX bit, quando il tipo di dato "nativo" (cioè quello che il processore considera come un'"unità", tecnicamente chiamato "word" del processore) è rappresentato con XX bit.
Solitamente questo implica che anche il bus dati (cioè il canale di comunicazione che permette di scambiare dati tra diverse componenti), il bus indirizzi (il bus usato dal processore per stabilire da quale punto leggere/scrivere), e i registri del processore abbiano dimensione pari a XX bit, tuttavia questo non è sempre vero.
Per estensione, si dice che un computer è a XX bit, se monta un processore a XX bit.

Voglio far notare che i processori della famiglia x86 sono retrocompatibili con le istruzioni utilizzate nei processori della stessa famiglia, però con word più piccole.
Ad esempio, processori x86 a 64 bit (che equivalgono ad 8 byte) possono eseguire codice pensato per processori x86 a 32 bit e precedenti, che a loro volta possono eseguire codice pensato per processori a 16 bit e precedenti, e così via.

Sebbene possa sembrare banale a questo punto, è importante notare che perché un programma (o sistema operativo, visto che comunque trattasi di un programma), "sfrutti gli XX bit" di un processore, è necessario compilarlo per quel tipo di processore.
Dunque, anche in quel programma, la word verrà considerata di grandezza pari a XX bit.
Anche qui, per estensione, si parla di programma o sistema operativo a XX bit.

Mentre BIOS all'avvio permette di usare AL MASSIMO codice che si usava sull'8086, quindi comunque MOLTO LIMITATO anche nell'accesso ai registri (basti pensare che durante la fase d'avvio, un processore a 32 bit può eseguire codice che opera al massimo sui primi 16 bit di ogni registro), UEFI invece, permette di eseguire codice in base alla word effettiva del processore.
Lo standard UEFI stabilisce che il firmware di una scheda madre può essere compilato per l'esecuzione su processori a 32 bit (quindi si parla di firmware UEFI a 32 bit), oppure per l'esecuzione su processori a 64 bit (qui si parlerà di firmware UEFI a 64 bit).

Facendo un'ultima volta riferimento al firmware BIOS, c'è da aggiungere che se su un computer con quel tipo di firmware veniva montato un processore a 64 bit, poco importava quale sistema venisse installato, visto che comunque, BIOS faceva eseguire codice in modalità reale, per poi passare alla modalità protetta una volta avviato un sistema operativo.
Essendo la famiglia x86 retrocompatibile, era tranquillamente possibile avere un processore a 64 bit, con su installato un sistema operativo a 32 bit (ovviamente non era possibile il contrario).

Putroppo UEFI non fa lo stesso ragionamento, infatti non è possibile eseguire programmi efi compilati per UEFI 32 bit, su UEFI 64 bit.
Su UEFI è possibile eseguire solo programmi efi compilati per il firmware CHE SI STA UTILIZZANDO, quindi programma efi a 32 bit implica UEFI 32 bit, programma efi a 64 bit implica UEFI 64 bit.
Sebbene in teoria questo fatto non dovrebbe comportare limitazioni circa i tipi di sistemi operativi installabili (visto che la limitazione sta negli eseguibili efi), nella pratica è necessario che il kernel del sistema operativo eseguito, abbia la stessa word del firmware UEFI utilizzato.
Di conseguenza, NON È POSSIBILE installare sistemi a 32 bit su UEFI a 64 bit e viceversa.
L'unica eccezione a questa regola pare essere il kernel Linux, grazie infatti alla modalità "mixed mode" di alcuni boot loader usati su tale piattaforma, pare sia possibile eseguire un kernel Linux a 64 bit, da un firmware UEFI a 32 bit.

Lettura del disco fisso secondo UEFI

UEFI contrariamente a BIOS, non sfrutta il Master Boot Record, cioè il primo settore, per stabilire quale sistema operativo avviare.
Lo standard stabilisce che all'inizio del disco dev'esserci una partizione in particolare, formattata con un file system che sia compatibile con lo standard FAT (di solito si utilizza fat32 o fat16), di dimensione variabile (si usa solitamente una dimensione pari o superiore a 512 Mebibyte).
Questa partizione viene denominata ESP (EFI System Partition) e qui verranno immagazzinati tutti i programmi efi, che poi verranno avviati in ambiente UEFI.

Quando durante l'avvio si giunge alla lettura del disco, il firmware UEFI fa controllare al computer il contenuto di alcune variabili risiedenti nella NVRAM della scheda madre (abbiamo detto in precedenza che in questa memoria sono immagazzinate tutte le impostazioni usate dai firmware).
Tali variabili fanno riferimento a programmi efi che risiedono sull'ESP e tutte insieme, formano un ordine di avvio (modificabile dalle impostazioni del firmware), in altri termini, esse stabiliscono l'ordine con cui vanno eseguiti i vari programmi efi, che nel caso più semplice, altro non sono che boot loader di un sistema operativo.
Il computer, in base a quest'ordine, cercherà di avviare il primo programma efi che viene trovato nella partizione ESP.
Se un programma efi referenziato da una certa variabile non viene trovato, viene letta la variabile successiva.
Così facendo dunque, è possibile eseguire sistemi operativi.

UEFI: lo schema di partizionamento GPT

Prima di iniziare a parlare dello schema di partizionamento GPT, è doverosa una premessa, circa gli schemi di partizionamento previsti da UEFI.

Sebbene MBR presenti molte limitazioni su un sistema moderno, lo standard UEFI prevede totale compatibilità con tale schema di partizionamento, a patto che sia presente all'inizio del disco, una partizione che faccia da ESP.
Di conseguenza, dovrebbe essere possibile eseguire sistemi operativi in maniera nativa, anche utilizzando questo schema.

Purtroppo nella pratica non è sempre così:
In primo luogo, ci sono implementazioni dello standard UEFI che abilitano, in presenza di un disco fisso con schema MBR, il CSM (il modulo di compatibilità discusso in precedenza).
In secondo luogo, ci sono installatori di sistemi operativi (come quelli dei vari Windows), che anche se avviati correttamente in modalità UEFI, in presenza di un disco con schema MBR, impediscono l'installazione, dichiarando che per continuare è necessario formattare l'intero disco con lo schema GPT.
I due casi sopracitati sono esempi di violazione dello standard.

Detto questo, lo standard UEFI predilige l'utilizzo dello schema di partizionamento GPT (che sta per GUID Partition Table).
Il nome è dovuto al fatto che GPT utilizza i GUID (Globally Unique Identifier) per riferirsi alle singole partizioni.
In generale, i GUID (o UUID, Universally invece di Globally) sono valori a 128 bit (equivalenti a 16 byte), utilizzati per identificare una qualunque entità software, in questo caso, le singole partizioni.
Si è calcolato che la probabilità che due entità diverse vengano identificate utilizzando lo stesso GUID è molto vicina allo 0.
Questo permette di asserire che si può referenziare ogni entità in maniera univoca usando un GUID.

Questo schema di partizionamento permette una dimensione massima di 8 ZiB (Zebibyte) a partizione, assumendo sempre 512 byte di dimensione, per un singolo settore.
Il motivo della cifra è presto detto: Contrariamente a MBR, GPT utilizza valori a 64 bit per far riferimento ai settori, pertanto, sono indirizzabili 2^64 settori, per un totale di spazio richiesto pari a 512 * (2^64) = 8 ZiB.
Per rendere l'idea, 1 Zebibyte = 2^30 Tebibyte = 2^70 byte, in altre parole, abbiamo uno spazio massimo dell'ordine di 8 miliardi di Terabyte (di poco maggiore in realtà, essendo Tebibyte).
Anche qui, dimensione del singolo settore diversa, implica un limite diverso.

Un disco partizionato con GPT ha la seguente struttura:

  • Il settore 0 (primo) viene definito come "MBR protettivo".
    È a tutti gli effetti un Master Boot Record, tuttavia, esso ha lo scopo di evitare che sistemi operativi che NON supportano UEFI e GPT, possano applicare modifiche sul disco.
    Se un computer con firmware BIOS legge questo MBR, riconoscerà il disco come una singola partizione con file system sconosciuto, e molti programmi che gestiscono dischi, non permetteranno modifiche.
  • Il settore 1 (secondo) viene definito come "Partition Table Header" (testa della tabella delle partizioni).
    Qui vengono riportate tutte le informazioni inerenti il disco, come ad esempio:
    • Il numero di partizioni esistenti;
    • In quale settore inizia la prima partizione;
    • L'UUID che rappresenta il disco stesso;
  • Tabella delle partizioni (dal settore 2 al settore 33 incluso, cioè dal terzo al trentaquattresimo):
    Qui risiedono tutte le informazioni inerenti le singole partizioni.
    Esempi di informazioni sono:
    • Gli UUID della partizione:
      • UUID di tipo:
        Cioè, l'UUID che identifica lo scopo della partizione.
        Tale UUID è uguale per tutte le partizioni dello stesso tipo.
        Ad esempio, tutte le partizioni ESP, hanno come UUID di tipo il valore "C12A7328-F81F-11D2-BA4B-00A0C93EC93B".
      • UUID di identificazione:
        Cioè, l'UUID che identifica la partizione stessa, a prescindere dal suo scopo.
        Così è possibile distinguerla dalle altre presenti nello stesso disco.
    • Dove si trova la partizione nel disco.
  • Le partizioni effettive:
    In teoria è possibile avere un numero "infinito" di partizioni, tuttavia, anche qui, come già discusso nel caso della "partizione estesa" nello schema MBR, i sistemi operativi tenderanno a limitare il numero di partizioni riconosciute.
  • Copia dei settori 1, 2 fino a 33.
    GPT si dice essere uno schema "ridondante", nel senso che scrive le stesse informazioni riportate prima, anche alla fine del disco.
    Lo scopo di ciò è principalmente il recupero delle informazioni in caso di problemi.

Alcune considerazioni su GRUB

Come ho già scritto all'inizio del post, il mio problema principale riguardava la sola installazione dei sistemi operativi, con conseguente installazione del boot manager, in particolare Debian con boot manager GRUB.

In base a ciò che è stato detto, il metodo per installare sistemi operativi e permetterne l'avvio, cambia profondamente tra i due standard, ed è pertanto necessario conoscere che cosa va fatto ond'evitare di rendere il sistema inutilizzabile.

firmware BIOS

Su questo tipo di firmware, GRUB andava installato (nella maggior parte dei casi) sul Master Boot Record.
Solitamente, per semplicità di chi andava a farsi un sistema cosidetto "multiboot" (cioè con sistemi operativi multipli), c'era la convenzione di installare PRIMA Windows e POI qualunque altra cosa.
Questo perché Windows, ad ogni installazione, sovrascrive il boot loader che risiede nel Master Boot Record, con conseguente inabilità di eseguire sistemi al di fuori di Windows.

Purtroppo chi si affacciava la prima volta a queste cose, commetteva l'errore di installare PRIMA GNU/Linux (o quello che era) e POI Windows.
Nel caso di GNU/Linux con boot manager GRUB, era possibile risolvere questo problema usando una distribuzione live esterna (ad esempio il GParted Live CD) e avviando una sessione chroot del sistema GNU/Linux installato.
Infine, bastava digitare un comando simile a questo:

grub-install <HD_DEV> --boot-directory=<BOOT_DIR>

dove HD_DEV è il dispositivo a blocchi del disco fisso e BOOT_DIR la cartella dove è montata la partizione di "boot" (in sistemi semplici, corrisponde alla cartella "/boot" della partizione GNU/Linux), utilizzata per immagazzinare i file d'avvio, tra i quali i kernel, e il file di configurazione di GRUB.

A sistema riavviato, era possibile avviare nuovamente ANCHE GNU/Linux, perché il boot loader era stato sovrascritto.

firmware UEFI

Sui firmware UEFI al contrario, non è strettamente necessario reinstallare GRUB.

Come abbiamo già detto, in questi firmware, sono i programmi efi a permettere l'avvio di sistemi operativi, ed inoltre, l'ambiente UEFI sfrutta l'ordine d'avvio memorizzato in NVRAM.
Gli installatori dei sistemi operativi, oltre a piazzare i loro programmi efi sulla partizione ESP, tendono ad impostare anche la prima variabile inerente l'ordine d'avvio.
Conseguenza di ciò, al riavvio, il sistema operativo che stanno installando, verrà eseguito per primo.

Come è possibile intuire, in situazioni normali non conta quale sistema operativo si installi per primo, perché in caso di necessità, il firmware permette la modifica da parte dell'utente delle voci inerenti l'ordine d'avvio.
Se pertanto si è installato prima GNU/Linux, poi Windows e ci si accorge che si avvia solo Windows, basta banalmente modificare tali voci, e reimpostare GNU/Linux come priorità.
Se il menù del firmware non lo permette, è possibile usare la shell efi, se neanche questo è possibile, allora si necessita per forza di un disco tipo GParted Live CD, tuttavia, il ricorso a questo mezzo, serve solo in caso di menù delle impostazioni estremamente limitato.

È necessario reinstallare GRUB invece, quando magari, per errore, vengono cancellati i programmi efi riguardanti GRUB, oppure se gli stessi sono corrotti.
Anche qui, bisognerebbe eseguire un disco esterno in modalità UEFI (perché no, anche il GParted Live CD), effettuare la sessione chroot, ma ricordarsi di montare ANCHE la partizione ESP e in seguito, reinstallare usando un comando del genere:

grub-install <HD_DEV> --boot-directory=<BOOT_DIR> --efi-directory=<EFI_DIR>

dove HD_DEV sarà il dispositivo a blocchi del disco fisso, BOOT_DIR sarà la cartella dove è montata la partizione boot già descritta in precedenza e infine EFI_DIR, sarà la cartella dove è stata montata la partizione ESP.


In conclusione, abbiamo discusso oggi dei due standard inerenti il firmware e di come UEFI abbia surclassato BIOS in quasi tutti i fronti.
I computer odierni montano oramai UEFI e ben presto verrà rimossa la compatibilità col vecchio firmware.
Come tutto ciò che è stato usato per molto tempo, anche BIOS ha fatto storia.

Bene, spero che il post vi sia piaciuto e che lo abbiate trovato utile, soprattutto a livello informativo.
Saluti da Antonio Daniele.
Ci si vede la prossima volta.

Torna in cima, Condividi, Guarda i commenti o Commenta tu stesso!