引导加载程序参数通过参数寄存器传递给 Linux 内核 (MIPS 24KEc)
Boot loader arguments passed to the Linux kernel via argument registers (MIPS 24KEc)
我正在尝试在包含 MIPS 24KEc 处理器的交换机上使用 custom bootloader 启动压缩内核 (vmlinuz)。这个引导加载程序不是我写的,它存在于产品的 NOR 闪存中,源代码由供应商在他们的 GPL 存档中提供。
引导加载程序从闪存中的固定位置读取 header,其中包含:
- Header 魔法 (SPIM)
- 内核加载地址
- 要加载的数据长度
- 内核入口地址
然后将header后面的num_bytes复制到内核加载地址,并跳转到指定的入口地址。引导命令行和 initrd 被编译到内核映像中(通过 CONFIG_CMDLINE 和 CONFIG_INITRAMFS_SOURCE)。
未压缩的内核映像 (vmlinux) 正常启动。当我尝试启动压缩内核时,解压器或内核没有任何输出。
我注意到 Linux kernel saves the argument registers 在清除 BSS 并跳转到解压器之前(来自 arch/mips/boot/compressed/head.S):
start:
/* Save boot rom start args */
move s0, a0
move s1, a1
move s2, a2
move s3, a3
我是 MIPS 汇编的新手,但我知道上面的移动语句是将参数寄存器保存到已保存的寄存器。保存的寄存器在内核解压后跳转到内核入口点之前恢复:
move a0, s0
move a1, s1
move a2, s2
move a3, s3
PTR_LI k0, KERNEL_ENTRY
看了u-boot源码,想知道this call in boot_jump_linux是否对应上面提到的"boot rom start args":
kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env,
linux_extra);
我找不到任何内核文档来解释内核期望引导 rom 在寄存器 a0、a1、a2 和 a3 中传递给它的参数。
适用于您的平台的函数 prom_init_cmdline
应该实现从 fw_arg0
读取引导参数 (argc
) 的数量和从 [=] 读取引导参数 (argv
) 14=]。如果此函数缺失或为空,您将必须定义它以从引导加载程序接收引导参数。
没有输出的问题原来是供应商内核无法从引导加载程序读取参数(没有prom_init_cmdline
),并且依赖于通过[=16将引导参数编译到内核中=].
我没有内核输出的原因是我没有用CONFIG_CMDLINE
编译内核,因此它没有输出到uart。我 patched the vendor kernel 接受引导加载程序在寄存器 a1
中传递的引导参数,并在 uart 上获得输出。
我正在尝试在包含 MIPS 24KEc 处理器的交换机上使用 custom bootloader 启动压缩内核 (vmlinuz)。这个引导加载程序不是我写的,它存在于产品的 NOR 闪存中,源代码由供应商在他们的 GPL 存档中提供。
引导加载程序从闪存中的固定位置读取 header,其中包含:
- Header 魔法 (SPIM)
- 内核加载地址
- 要加载的数据长度
- 内核入口地址
然后将header后面的num_bytes复制到内核加载地址,并跳转到指定的入口地址。引导命令行和 initrd 被编译到内核映像中(通过 CONFIG_CMDLINE 和 CONFIG_INITRAMFS_SOURCE)。
未压缩的内核映像 (vmlinux) 正常启动。当我尝试启动压缩内核时,解压器或内核没有任何输出。
我注意到 Linux kernel saves the argument registers 在清除 BSS 并跳转到解压器之前(来自 arch/mips/boot/compressed/head.S):
start:
/* Save boot rom start args */
move s0, a0
move s1, a1
move s2, a2
move s3, a3
我是 MIPS 汇编的新手,但我知道上面的移动语句是将参数寄存器保存到已保存的寄存器。保存的寄存器在内核解压后跳转到内核入口点之前恢复:
move a0, s0
move a1, s1
move a2, s2
move a3, s3
PTR_LI k0, KERNEL_ENTRY
看了u-boot源码,想知道this call in boot_jump_linux是否对应上面提到的"boot rom start args":
kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env,
linux_extra);
我找不到任何内核文档来解释内核期望引导 rom 在寄存器 a0、a1、a2 和 a3 中传递给它的参数。
适用于您的平台的函数 prom_init_cmdline
应该实现从 fw_arg0
读取引导参数 (argc
) 的数量和从 [=] 读取引导参数 (argv
) 14=]。如果此函数缺失或为空,您将必须定义它以从引导加载程序接收引导参数。
没有输出的问题原来是供应商内核无法从引导加载程序读取参数(没有prom_init_cmdline
),并且依赖于通过[=16将引导参数编译到内核中=].
我没有内核输出的原因是我没有用CONFIG_CMDLINE
编译内核,因此它没有输出到uart。我 patched the vendor kernel 接受引导加载程序在寄存器 a1
中传递的引导参数,并在 uart 上获得输出。