The kernel entrypoint for the Zircon kernel calls platform_early_init() where it gets the zbi_paddr from the .S file and then passes to pdev_init
void* zbi_vaddr = paddr_to_physmap(zbi_paddr);
zbi_header_t* header = (zbi_header_t*)zbi_vaddr;
ramdisk_base = header;
zbi_root = reinterpret_cast<zbi_header_t*>(ramdisk_base);
pdev_init(zbi_root);
Where pdev_init is responsible for starting drivers like uart.
It looks like the drivers through pdev_run_hooks (on the same file), where it walks through the zbi file and finds each driver information.
So it looks like ZBI is essential for booting?
I ask because I compiled the zircon kernel and got
lz@vm:~/fuchsia/out/default/kernel_arm64$ ls gen
image.build-id.stamp kernel.zbi toolchain.ninja zircon.elf.build-id.stamp zircon.elf.map image image.map
obj zircon.elf zircon.elf-gdb.py
as you see it produces a zircon.elf, which theoretically could be ran, but I think ZBI information is essential for booting otherwise it would panic. Am I right?
Zircon expects the bootloader to pass up a Zircon Boot Image (ZBI) object that it can parse.
This image contains a lot of information that is useful for system startup, for example, it contains physical memory ranges, the kernel cmdline, cpu topology information, peripherals information, and even a read-only filesystem used for bootstrapping userspace.
You can read more in the "Zircon Kernel to userspace bootstrapping" documentation. The ZBI Format is described in
zircon/system/public/zircon/boot/image.h.In the
vim2branch for the u-boot repo, you can see how the bootloader assembles and appends the zbi items before booting into zircon.