我尝试在QEMU自己创建的机器上引导预编译的内核。
配置了串行外围设备,我成功地可以为此机器引导预编译的U-boot映像。
在U-Boot中,所有串行IO都可以正常工作(在机器设置中还准备了内存地址和UART地址)。使用-nographic选项,我可以在UBoot命令提示符下进行读写。
我可以在Uboot中发出bootm命令以将内核加载到RAM并引导它。我看到的最后一个字符串是“正在解压缩Linux ...完成。正在启动内核...”。
那里有黑屏。
主要区别在于内核的工作原理是因为使用远程GDB会话,我看到它使用printk函数打印输出,例如Banner和更多信息。但是在QEMU屏幕上我什么都没有。
问题:早期在内核中的哪里进行console = ttyS0,115200的设置?我试图在内核源代码中进行搜索,但找不到调试问题的地方。
在设置内核之前,内核如何知道要传递给串行的内容?有RAM环形缓冲区吗?
有任何线索吗?
答案 0 :(得分:0)
当您为ARM机器引导预编译的U-Boot映像时,它已经包括:内核,initramfs / initrd文件以及已编译为U-Boot映像格式的已编译设备树二进制(.dtb)文件。可以识别,解压缩,加载到内存中并用于启动启动过程。在这种情况下,原始设备树规范(DTS)文件的.dtb文件中包含console = ttyS0,115200信息,该文件将包含一个类似于以下内容的部分:
chosen {
bootargs = "console=ttyS0,115200n8 maxcpus=2, envaddr = <0xfa0f0000>";
};
最终,U-Boot将二进制.dtb文件加载到内存中,并将指向该文件的指针传递给内核,然后内核可以推断出控制台参数并显示控制台输出。
相反,当您希望将内核加载到内存中并使用U-Boot bootm命令时,必须自己确保已将initramfs / initrd和.dtb文件加载到内存中(也许通过tftp),并且地址是作为参数传递给bootm。完成此操作后,内核将有机会像在U-Boot映像情况下一样,从.dtb中获取控制台参数,然后您应该会看到控制台输出。在4.19内核中,要执行此操作的内核代码位于drivers / of / base.c of_console_check()中。
如果该答案有帮助,请考虑将其标记为最终答案-谢谢。祝您好运,启动QEMU并运行控制台输出!