assembly - 引导加载程序参数通过参数寄存器传递到 Linux 内核 (MIPS 24KEc)

标签 assembly linux-kernel mips

我正在尝试使用 custom bootloader 启动压缩内核 (vmlinuz)在包含 MIPS 24KEc 处理器的交换机上。我没有编写此引导加载程序,它存在于产品的 NOR 闪存中,并且源代码由供应商在其 GPL 存档中提供。

引导加载程序从闪存中的固定位置读取 header ,其中包含:

  1. 标题魔术 (SPIM)
  2. 内核加载地址
  3. 要加载的数据长度
  4. 内核入口地址

然后它将 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)来自fw_arg1。如果此函数丢失或为空,您必须定义它才能从引导加载程序接收引导参数。

无输出的问题原来是供应商内核无法从引导加载程序读取参数(没有 prom_init_cmdline),并且依赖于通过 将引导参数编译到内核中>CONFIG_CMDLINE

我没有从内核输出的原因是我没有使用CONFIG_CMDLINE编译内核,因此它没有输出到uart。我patched the vendor kernel接受引导加载程序在寄存器 a1 中传递的引导参数,并在 uart 上获取输出。

关于assembly - 引导加载程序参数通过参数寄存器传递到 Linux 内核 (MIPS 24KEc),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60979706/

相关文章:

assembly - ARM Cortex-M4 互斥锁。 DMB指令

linux-kernel - 从内核模块到设备的 I/O 失败并显示 EFAULT

android - 为 android x86 编译 CUPS

assembly - 从汇编解码为机器码(Y86)时如何确定程序计数器?

linux - 如何创建一个777权限的目录?

Linux 内核构建 : Perform "make localmodconfig" non-interactive way

mips - 在 6 级标量或超标量 MIPS 中,如果发生错误预测,需要杀死多少条指令?

mips - 如果使用异步组件,是否可能出现 "single cycle cpu"?

assembly - 我们如何在汇编代码 (MIPS) 中取消引用指针?

string - MIPS 问题 : Returning ($v0), 参数、jal 和 jr $ra(包含代码)