C’est la fonction dans le fichier bootm.c de u-boot à partir duquel le kernel est lancé:
/* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { #ifdef CONFIG_ARM64 void (*kernel_entry)(void *fdt_addr); int fake = (flag & BOOTM_STATE_OS_FAKE_GO); kernel_entry = (void (*)(void *fdt_addr))images->ep; debug("## Transferring control to Linux (at address %lx)...\n", (ulong) kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); announce_and_cleanup(fake); if (!fake) kernel_entry(images->ft_addr); #else unsigned long machid = gd->bd->bi_arch_number; char *s; void (*kernel_entry)(int zero, int arch, uint params); unsigned long r2; int fake = (flag & BOOTM_STATE_OS_FAKE_GO); kernel_entry = (void (*)(int, int, uint))images->ep; s = getenv("machid"); if (s) { ssortingct_strtoul(s, 16, &machid); printf("Using machid 0x%lx from environment\n", machid); } debug("## Transferring control to Linux (at address %08lx)" \ "...\n", (ulong) kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); announce_and_cleanup(fake); if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) r2 = (unsigned long)images->ft_addr; else r2 = gd->bd->bi_boot_params; if (!fake) kernel_entry(0, machid, r2); #endif }
J’ai du mal à comprendre comment kernel_entry
fonctionne ici. Surtout dans l’avant dernière ligne, il est utilisé comme:
kernel_entry(0, machid, r2);
Alors, où est la définition de kernel_entry()
? Je n’ai pas réussi à trouver l’intégralité du code source u-boot et du kernel.
Mettre à jour
Je reformule ma question ici:
Supposons que kernel_entry
est un pointeur sur une fonction et est défini comme suit:
bootm_headers_t *images kernel_entry = (void (*)(int, int, uint))images->ep;
Ensuite, quelque part dans le programme, il est appelé comme:
kernel_entry(0, machid, r2);
Je comprends être un pointeur, kernel_entry
devrait stocker l’adresse d’une fonction. Mais je veux comprendre quelles opérations seront effectuées sur les trois arguments. Pourquoi avons-nous ces arguments?
La déclaration de la variable kernel_entry
et son type, qui est un pointeur sur une fonction prenant int
, int
, uint
et retournant void
(probablement la partie la plus déroutante), est ici:
void (*kernel_entry)(int zero, int arch, uint params);
Assignation, images->ep
est converti en pointeur de fonction de signature souhaité et placé dans la variable:
kernel_entry = (void (*)(int, int, uint))images->ep;
Enfin, la fonction s’appelle:
kernel_entry(0, machid, r2);
Veuillez noter que si CONFIG_ARM64 est défini, la fonction sur kernel_entry
pointe kernel_entry
a une signature différente:
void (*kernel_entry)(void *fdt_addr); //takes one void* param and returns void
U-Boot a l’image du kernel dans son espace mémoire adressable, lit une adresse contenue dans cette image (sur images-> ep) et se twig sur cette adresse de point d’entrée.
La “définition de kernel_entry ()” est en réalité dans le code source du kernel, le libellé “start” dans arch / arm / boot / compressé / head.S est ce que vous recherchez.
Pour comprendre le processus de démarrage du kernel, le premier tutoriel d’OMI est le chapitre 5 de Hallinan “Embedded Linux Primer”.