Manually boot Linux, how to pass initrd, dtb, command line to Kernel?

Viewed 44

I am trying to boot ARMv8 Linux totally manually, which means there is NO bootloader at all in hand. I can load the kernel image, initrd and fdt to memory, then 'jump' to the kernel entry point to boot it.
But I don't know how to tell the kernel where is the initrd or dtb, and what is the kernel command line.. :-(.
So the question on ARMv8 Linux is what is the way to pass info of initrd, dtb and command line to the kernel, without using bootloader ?

The uboot code of bootm for ARM is as follows (arch/arm/lib/bootm.c),

    if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len)
        r2 = (unsigned long)images->ft_addr;
    else
        r2 = gd->bd->bi_boot_params;

    if (!fake) {
#ifdef CONFIG_ARMV7_NONSEC
        if (armv7_boot_nonsec()) {
            armv7_init_nonsec();
            secure_ram_addr(_do_nonsec_entry)(kernel_entry,
                              0, machid, r2);
        } else
#endif
            kernel_entry(0, machid, r2);
    }
#endif

With fdt loaded into memory, the r2 is fdt memory address.
The entry point of Linux kernel (5.19.9) of ARM64 is as follows (arch/arm64/kernel/head.S),

/*
 * Preserve the arguments passed by the bootloader in x0 .. x3
 */
SYM_CODE_START_LOCAL(preserve_boot_args)
    mov x21, x0             // x21=FDT

    adr_l   x0, boot_args           // record the contents of
    stp x21, x1, [x0]           // x0 .. x3 at kernel entry
    stp x2, x3, [x0, #16]

    dmb sy              // needed before dc ivac with
                        // MMU off

    add x1, x0, #0x20           // 4 x 8 bytes
    b   dcache_inval_poc        // tail call
SYM_CODE_END(preserve_boot_args)

It seemd that kernel thinks X0 is the address of fdt (or boot args).
So what register is used to pass FDT to kernel in the bootup ?

0 Answers
Related