QEMU - "Booting kernel" 后没有内核输出

QEMU - No kernel output after "Booting kernel"

我尝试在QEMU自建机上启动预编译内核

串口外设配置完成,我可以成功启动本机预编译的U-boot镜像

在 U-Boot 中,所有串行 IO 都运行良好(内存寻址和 UART 地址也在机器设置中准备好)。使用选项 -nographic 我可以在 UBoot 命令提示符下读写。

我可以在 Uboot 中发出 bootm 命令将内核加载到 RAM 并启动它。我看到的最后一个字符串是 "Uncompressing Linux...done. Booting kernel...".

然后出现黑屏。

主要区别在于内核工作,因为使用远程 GDB 会话我看到它使用 printk 函数打印横幅等输出和更多信息。但是在 QEMU 屏幕上我有 none.

问:早期内核中哪里设置了console=ttyS0,115200 setup?我试图在内核源代码中搜索,但找不到调试问题的地方。

内核如何知道在设置之前要传递给串口的内容?是否有 RAM 环形缓冲区?

有什么线索吗?

当您为 ARM 机器启动预编译的 U-Boot 映像时,它已经包含:一个内核、一个 initramfs/initrd 文件和一个编译成映像格式的设备树二进制 (.dtb) 文件U-Boot 可以识别、解压缩、加载到内存并用于启动启动过程。在这种情况下,console=ttyS0,115200 信息包含在原始设备树规范 (DTS) 文件的 .dtb 文件中,该文件将包含如下所示的部分:

chosen {
    bootargs = "console=ttyS0,115200n8 maxcpus=2, envaddr = <0xfa0f0000>";
};

最终 U-Boot 将二进制 .dtb 文件加载到内存中并将指向它的指针传递给内核,然后内核可以推断出控制台参数并显示控制台输出。

当您更喜欢将内核加载到内存中并使用 U-Boot bootm 命令时,您必须自己确保 initramfs/initrd 和 .dtb 文件已加载到内存中(可能通过 tftp)并且地址作为参数传递给 bootm。一旦完成,内核就有机会从 .dtb 中获取控制台参数,就像它在 U-Boot 映像中所做的那样,然后您应该会看到控制台输出。执行此操作的内核代码在 4.19 内核中位于 drivers/of/base.c of_console_check().