试图了解函数指针的用法

这是u-boot的bootm.c中启动内核的函数:

/* 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) { strict_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 } 

我很难理解kernel_entry是如何在这里工作的。 特别是在倒数第二行,它被用作:

  kernel_entry(0, machid, r2); 

那么kernel_entry()的定义在kernel_entry() ? 我没有发现整个u-boot和内核源代码。

更新

我在这里重述我的问题:

假设kernel_entry是一个指向函数的指针,被定义为:

 bootm_headers_t *images kernel_entry = (void (*)(int, int, uint))images->ep; 

然后在程序的某个地方被称为:

  kernel_entry(0, machid, r2); 

我明白作为一个指针, kernel_entry应该存储一个函数的地址。 但是我想知道这三个参数将会被执行什么操作。 为什么我们有这些论点?

Solutions Collecting From Web of "试图了解函数指针的用法"

kernel_entry变量及其类型的声明,它是一个指向intintuint和返回void (可能是最容易混淆的部分)的函数的指针,在这里:

 void (*kernel_entry)(int zero, int arch, uint params); 

赋值, images->ep被转换成所需的签名函数指针,并放入变量:

 kernel_entry = (void (*)(int, int, uint))images->ep; 

最后,这个函数被调用:

 kernel_entry(0, machid, r2); 

请注意,如果CONFIG_ARM64被定义,那么函数kernel_entry指向具有不同的签名:

 void (*kernel_entry)(void *fdt_addr); //takes one void* param and returns void 

U-Boot在其可寻址的内存空间中具有内核映像,读取该映像中包含的地址(在images-> ep),并分支到该入口点地址。

kernel_entry()的定义实际上是在内核源代码中,arch / arm / boot / compressed / head.S上的标签“start”就是你要找的东西。

为了理解内核启动过程,IMO定义的教程是Hallinan“Embedded Linux Primer”的第5章。