Version 23 (modified by 8 years ago) (diff) | ,
---|
Boot procedure
A) General Principles
The ALMOS-MKH boot procédure can be decomposed in two phases:
- The architecture dependent phase, implemented by the boot_loader procedure.
- The architecture indépendant phase, inplemented by the kernel-init procedure.
As the generic (i.e. architecture independent) kernel initialization procedure is executed in parallel by all kernel instances in all clusters containing at least one core and one memory bank, the main task of the boot-loader is to load - in each cluster - a local copy of the ALMOS-MKH kernel code, including a description of the hardware architecture, contained in the boot_info_t data-structure.
This structure is build by the boot-loader and stored at the beginning of the local copy of the kdata segment. It contains both general and cluster specific informations:
- general hardware architecture features : number of clusters, the topology, etc.
- available external (shared) peripherals : types and features.
- number of cores in cluster,
- available internal (private) peripherals in cluster : types and features.
- available physical memory in cluster.
This boot_info_t structure is defined in the boot_info.h file.
To build the various boot_info_t structures (one per cluster), the boot-loader uses the arch_info_t binary structure, that is described in section Hardware Platform Definition. This binary structure is contained in the arch_info.bin file, and must be stored in the file system root directory.
This method allows -in principle - the boot_loader to check and reconfigure the hardware components, to guaranty that the generated boot_info_t structures contain only functionally tested hardware components.
We describe below the boot_loader for the TSAR architecture, the boot_loader for the I86 architecture, and the generic kernel initialization procedure.
B) Boot-loader for the TSAR architecture
The TSAR boot-loader uses an OS-independant pre-loader, stored in an external ROM, and in charge of loading the TSAR boot-loader code from an external block-device to the memory. This preloaded is specific for the TSAR architecture, but independent on the Operating System. It is used by ALMOS-MKH, but also by LINUX, NetBSD, or the GIET-VM.
The TSAR boot_loader allocates - in each cluster containing a physical memory bank - five fixed size memory zones, to store various binary files or data structures :
size local physical address préloader code itself PRELOADER_MAX_SIZE (16 Kb) RELOADER_SIZE (0x0) boot-loader code local copy BOOT_MAX_SIZE (1 Mb) BOOT_BASE (0x100000) arch_info.bin file local copy ARCHINFO_MAX_SIZE (2 Mb) ARCHINFO_BASE (0x200000) kernel.elf binary file KERN_MAX_SIZE (1 Mb) KERN_BASE (0x400000) execution stacks (one per core) BOOT_STACK_SIZE (1 Mb) BOOT_STACK_BASE (0x500000)
The values given in this array are configuration parameters, that can be redefined in the boot_config.h file. This memory is only used for temporary storage : when the boot_loader completes, and transfer control to the kernel_init procedure, the kernel code (i.e. the code and data segments) has been copied at physical address 0x4000 in all clusters. The four pages (16 Kbytes) reserved for the prelloader are only used in cluster 0 and can be saved if the preloader is stored in an external ROM.
Le chargement d'ALMOS-MK sur l'architecture TSAR se fait donc en 4 phases: A core is identified by two indexes[cxy][lid] : cxy is the cluster identifier, an lid is the core local index in cluster cxy.
In all clusters, the core with local index 0 is called CP0.
B1. Preloader phase
At reset, the extension address registers (for both data and instructions) in all cores[cxy][lid] contain the 0 value. Therefore, all cores can only access the physical address space of cluster 0. If the preloaded is stored in an external ROM, the I/O cluster must be cluster 0, to access the external ROM.
All cores execute the same preloader code, but the work done depends on the core identifier. The core[0][0] (i.e. CP0 in cluster 0) load in local memory of cluster 0, at address the boot loader code. All other cores do only one task before going to sleep (low-power) state: each core activates its private WTI channel in the local ICU (Interrupt Controller Unit) to be wake-up by core [0][0], using an IPI (Inter Processor Interrupt).
This shows the memory content after this first phase.
B2. Sequencial phase
In this second phase the work is entirely done by core[0][0].
- Il initialise son pointeur de pile pour pouvoir exécuter du code C. La taille de cette pile temporaire est aussi un paramètre de configuration. Par défaut, le pointeur de pile du core CP0 de chaque cluster (lid = 0) est initialisé à l'adresse 0x600000.
- Le CP0 cu cluster (0,0) initialise 2 périphériques: TTY (canal 0) pour afficher les informations de débogage et IOC pour accéder aux fichiers sur disque.
- Il charge ensuite, toujours en mémoire locale du cluster de boot, le fichier binaire arch_info.bin ainsi que l'image binaire du noyau d'ALMOS-MK, respectivement à l'adresse 0x200000 et 0x400000, juste au dessus du segment mémoire correspondant à l'image du boot-loader.
- Il utilise les informations contenues dans la structure arch_info.bin pour initialiser les différents champs de la structure boot_info_t du cluster de boot.
- Il réveille les coeurs CP0 de tous les autres clusters.
- Il se met en attente jusqu'à ce que tous les autres CP0 arrivent à ce point de rendez-vous en utilisant une barrière de synchronisation.
Voici le contenu de la mémoire du cluster de boot et des autres clusters après cette deuxième étape.
B3. Phase partiellement parallèle
Dans chaque cluster, le coeur CP0, réveillé par le CP0 du cluster de boot, sort du preloader et exécute le code du boot-loader qui se trouve toujours stocké dans la mémoire physique du cluster(0,0), pour effectuer les tâches suivantes:
- Il analyse le contenu de la structure arch_info.bin (toujours stocké dans la mémoire physique du cluster de boot) en parcourant le tableau de descripteurs de core pour retrouver son identificateur de cluster cxy. Notons que cette étape est exécutée parallèlement par tous les CP0, ce qui entraine une contention au banc mémoire contenant ce tableau des descripteurs des coeurs.
- Il peut maintenant, à partir de son cxy, mettre à jour ses registres d'extension d'adresse pour accéder à la mémoire physique du cluster dans lequel il se trouve. Néanmoins, il continue à accéder au code de boot stocké dans le cluster (0,0) tant que le code du boot-loader n'a pas été copiée dans son banc de mémoire local.
- Il alloue sa pile de boot en initialisant son pointeur de pile à l'adresse 0x600000 dans l'espace adressable physique son cluster.
- Il copie l'image du boot-loader et le fichier arch_info.bin aux mêmes adresses, respectivement 0x100000 et 0x200000, dans la mémoire physique locale. À partir d'ici, chaque CP0 peut exécuter le code du boot-loader en local.
- Il copie ensuite l'image du noyau à l'adresse 0x4000 de la mémoire physique locale de son cluster (c'est à dire, juste après les quatre pages réservées au prélasser).
- Il utilise la structure arch_info.bin locale pour initialiser les différents champs de la structure boot_info_t de son cluster. Cette tâche n'utilise que des accès mémoire locaux puisque toutes les informations nécessaires sont disponibles localement.
- Il arrive à la barrière de synchronisation, et le dernier CP0 débloque tous les CP0 (y compris bscpu),
- Chaque CP0 envoie des IPIs pour réveiller les autres cores dans son cluster local.
- Les CP0 se mettent en attente jusqu'à ce que tous les autres cores arrivent à ce point de rendez-vous en utilisant le mécanisme de barrière de synchronisation.
Voici le contenu de la mémoire du cluster de boot et des autres clusters (appelés banalus) après cette troisième étape.
A4. Fully parallel phase
Chaque core CPi (lid non nul), réveillé par le CP0 local de son cluster, sort du code du preloader et exécute le boot-loader dans le cluster de boot puisque ses registres d'extension d'adresse ne sont pas encore mis à jour. Une fois sortis du preloader, ces cores décrémentent le compteur de la barrière de synchronisation et débloquent les CP0. Tous ces CP0 sauf un, se mettent tout de suite en attente jusqu'à ce que les CPi finissent leur exécution du boot-loader. Le seul CP0 qui n'arrive pas encore à cette barrière de synchronisation, celui du cluster(0,0), peut maintenant écraser le code du preloader en déplaçant l'image du noyau à l'adresse 0x0 de l'espace adressable physique du cluster(0,0), puisque tous les cores sont déjà sortis du preloader. Il rejoint ensuite les autres CP0 au dernier point de rendez-vous dans le boot-loader. Les CPi, quant à eux, exécutent, pour le moment, le code du boot-loader se trouvant dans le cluster de boot car leurs registres d'extension d'adresse ont toujours la valeur 0 par défaut. Chacun de ces CPi effectue les étapes suivantes:
- Il analyse le contenu de arch_info.bin (dans l'espace adressable physique du cluster de boot) en parcourant le tableau de descripteurs de core pour retrouver son identificateur de cluster cxy ainsi que son identificateur de core local dans son cluster lid. Notons que cette étape est exécutée parallèlement par tous les CPi, ce qui entraine une contention, encore plus forte que celle créée par les accès parallèles des CP0, au banc mémoire contenant ce tableau de descripteurs de core .
- Il peut maintenant, à partir de son cxy, mettre à jour les valeurs dans ses registres d'extension d'adresse de code et de données. Comme le CP0 du même cluster a déjà copié les informations nécessaires dans le banc mémoire local aux mêmes adresses que du cluster de boot, il peut toujours exécuter le code du boot-loader en local.
- Il alloue sa pile de boot en initialisant son pointeur de pile à l'adresse 0x600000 - 4K*lid dans l'espace adressable physique locale de son cluster (grâce à la nouvelle valeur dans le registre d'extension d'adresse de code).
- La structure boot_info_t du cluster étant déjà initialisée, chacun des CPi ne fait que vérifier les informations qui le concernent.
- Il arrive finalement au point de rendez-vous avec tous les CP0, décrémente le compteur de la barrière de synchronisation et se met en attente.
- Dès que le dernier core arrive à ce point et débloque les autres, tous les cores se branchent à la fonction kern_init().
Voici le contenu de la mémoire dans tous les clusters à la fin de la phase de boot, juste avant d'entrer dans le noyau d'ALMOS-MK.
Arrivé à ce point, le boot-loader a fini son travail, la description de la l'architecture matérielle contenue dans arch_info.bin a été analysée et stockée dans la variable globale de type boot_info_t du noyau, stockée dans le segment data du noyau. Dans chaque cluster, ALMOS-MK peut utiliser tout l'espace adressable physique occupé antérieurement par l'image du boot-loader, arch_info.bin et les piles de boot. La seule zone de mémoire persistante est l'image du noyau elle-même (les segments kcode et kdata), stockée à l'adresse 0x0 dans tous les clusters.
C) Boot-loader for the I86 architecture
TODO
D) Generic kernel initialization procedure
Attachments (4)
-
Phys_Mem1.svg (33.1 KB) - added by 8 years ago.
Contenu de l'espace adressable physique des clusters après phase 1
-
Phys_Mem2.svg (69.4 KB) - added by 8 years ago.
Contenu de l'espace adressable physique des clusters après phase 2
-
Phys_Mem3.svg (116.8 KB) - added by 8 years ago.
Contenu de l'espace adressable physique des clusters après phase 3
-
Phys_Mem4.svg (71.8 KB) - added by 8 years ago.
Contenu de l'espace adressable physique des clusters après phase de boot
Download all attachments as: .zip