这是u-boot的功能:
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
}
我从相关问题中了解到:Trying to understand the usage of function pointer kernel_entry
是指向 a 函数的指针。有人可以帮我理解定义函数的位置吗?我甚至不知道这个函数的名字,所以我没有grep
它。
注意:整个u-boot源代码为here。
答案 0 :(得分:2)
确实kernel_entry
是一个函数指针。它是从名为ep
的{{1}}传入的数据images
字段初始化的,类型为bootm_header_t
。 struct
的定义位于include/image.h
。这是可引导映像头的定义,即内核映像的头,其中包含从引导加载程序引导该映像的基本信息。显然,要启动它,您需要一个程序入口点,类似于常规C程序中的主要功能。
在该结构中,入口点简单地定义为内存地址(unsigned long
),您列出的代码将其转换为该函数指针。
通过在磁盘上加载映像文件的第一个块获得的结构,其位置已由引导加载程序已知。
因此,该函数指针指向的实际代码属于不同的二进制文件,并且函数的定义必须位于不同的源代码中。对于linux内核,此入口点是一个程序集手动编码函数,其源代码位于head.S
。这个函数高度依赖于arch,你会发现许多具有该名称的文件在内核树中实现它。