这是启动内核的u-boot's 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()
的定义在哪里?我没能找到整个u-boot和内核源代码。
更新
我在这里重新提出我的问题:
假设kernel_entry
是指向函数的指针,并被定义为:
bootm_headers_t *images
kernel_entry = (void (*)(int, int, uint))images->ep;
然后程序中的某个地方被称为:
kernel_entry(0, machid, r2);
我理解作为指针,kernel_entry
应该存储函数的地址。但我想了解将对这三个参数执行哪些操作。为什么我们有这些论点?
答案 0 :(得分:2)
kernel_entry
变量及其类型的声明,它是指向int
,int
,uint
和返回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
答案 1 :(得分:1)
U-Boot在其可寻址存储空间中具有内核映像,读取该映像中包含的地址(在images-> ep),并分支到该入口点地址。
kernel_entry()""定义实际上是在内核源代码中,标签" start"在arch / arm / boot / compressed / head.S是您正在寻找的。
要了解内核启动过程,IMO的权威教程是Hallinan" Embedded Linux Primer"的第5章。