c/c++语言开发共享如何优化U-boot到内核切换代码?

平台:Xilinx Zynq SoC上的ARM Cortex A9上的Linux。

我问了一个问题: 为什么内核启动太晚了

基本上我试图理解,然后最小化这两个事件之间的延迟:

[Sat Apr 12 19:33:50.692 2014] Starting kernel ... [Sat Apr 12 19:33:50.692 2014] [Sat Apr 12 19:33:51.298 2014] Booting Linux on physical CPU 0x0 

第一行告诉控件现在正在给内核,而第二行告诉控件现在是内核并且正在由CPU执行。

从u-boot到内核的这种切换对我们的应用程序来说花费了太多时间。

为了理解这两个事件之间发生了什么,我在下面插入了printf语句:

1- bootm.c

我把以下行放在函数static void boot_jump_linux(bootm_headers_t *images, int flag)

  } if (!fake) {printf("above kernel_entry in boot_jump_linux in bootm.cn"); kernel_entry(0, machid, r2); printf("below kernel_entry boot_jump_linux in bootm.cn"); } } 

2- main.c

我把这样的声明放在start_kernel函数中:

 asmlinkage void __init start_kernel(void) { printk("I am the first statement in start_kernel in main.c" ); char * command_line; extern const struct kernel_param __start___param[], __stop___param[]; 

然后我编译了u-boot和内核,新的日志消息包含以下行:

 [Sat Apr 12 19:33:50.692 2014] Starting kernel ... [Sat Apr 12 19:33:50.692 2014] above kernel_entry in boot_jump_linux in bootm.c [Sat Apr 12 19:33:51.298 2014] I am the first statement in start_kernel in main.c [Sat Apr 12 19:33:51.298 2014] Booting Linux on physical CPU 0x0 

(实际上我把printf语句放在很多地方但是所有的thsoe都在“启动内核……”或“在物理CPU 0x0上启动Linux”之下,所以我在这个讨论中忽略它。我也用ftrace来看热点,但它没有报告u-bootfunction)。

我观察到“bootm.c中boot_jump_linux中的kernel_entry下面”永远不会打印在日志消息中的任何地方。 这表明在函数kernel_entry(0,machid,r2)之后控件不会返回; 之所以被调用,是因为linux现在已经控制并正在执行。

所以我的目标是知道在这两个事件中正在执行哪个function。

现在要了解发生了什么(即使在插入我的printf / printk消息后仍未清楚)我问了以下问题:

1- 在u-boot中,kernel_entry指向哪个函数?

2- 试图理解函数指针的用法

基于那里的答案,我怀疑我的热点,即花费很多时间的代码位于以下文件之一:

1- https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/kernel/head.S

2- https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/kernel/head-common.S

3- https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/boot/compressed/head.S

我的问题:

1-我的理解是否正确,我应该专注于上述文件?

2-调用kernel_entry(0, machid, r2); 是的,控件转到上面的代码和哪一行?

我怀疑文件https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/boot/compressed/head.S对我没用,因为这是解压缩所必需的,但是我的内核已解压缩,因为在u-boot日志中可以很早地看到以下行:

 [Sat Apr 12 19:33:50.596 2014] Uncompressing Kernel Image ... OK 

完整的日志在这里 。

有人可以在这方面让我高兴吗?

提前谢谢了!!

    我的目标是尽可能快地进行切换。
    你认为使用早期的printk我可以更快地启动,因为切换会提前吗?

    您的问题以及计算“快速”或“延迟”的方法都是基于有缺陷的数据。

    您认为0.5秒“延迟”实际上是U-Boot 实时输出“Starting kernel …” ,而内核缓冲推迟输出其“Booting Linux”直到系统和控制台初始化。 这是将苹果与橙子进行比较。
    至少你必须通过启用早期的printk实时输出内核(就像U-Boot一样)。 然后您的时间戳将更好地指示实际经过的时间。

    Linux内核映射第18章的摘录(由我强调):

    在printk()的坚固性的盔甲中存在一个缝隙。 在控制台初始化之前,它在内核引导过程中的某个点之前是不可用的。 实际上,如果控制台没有初始化,输出应该在哪里?

    这通常不是问题,除非您在引导过程中很早就调试问题(例如,在setup_arch()中执行特定于体系结构的初始化)。 这样的调试是一个挑战,并且没有任何类型的打印方法只会使问题复杂化。

    有一些希望,但不是很多。 硬核架构黑客使用可以工作的硬件(比如串口)与外界进行通信。 相信我这对大多数人来说并不好玩。 一些受支持的架构确实实现了一个理智的解决方案,然而其他(包括i386)有可用的补丁,也节省了一天。

    解决方案是一个printk()变体,可以在引导过程的早期输出到控制台:early_printk()。 行为与printk()相同,只更改名称及其先前工作的能力。 然而,这不是可移植的解决方案,因为并非所有支持的体系结构都实现了这样的方法。 它可能会成为你最好的朋友,如果它确实如此。

    有关启用早期printk的详细信息,请参阅相同问题的答案 (由您的双胞胎?)。

    所以不,使用早期的printk不会改善“切换”或整体启动时间。
    但它应该有助于防止你寻找幻像障碍。

    我想知道怎么发生。

    您正在通过指向其他函数的函数指针显示直接函数调用。

    我没有看到除了中断代码之外的任何东西都会干扰它。

    所花费的时间是600毫秒,这并不是很多,但当然在很多情况下都很明显(特别是在Zynq相关的地方)。

    要调查的事情:

      以上就是c/c++开发分享如何优化U-boot到内核切换代码?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/523239.html

      (0)
      上一篇 2020年12月11日
      下一篇 2020年12月11日

      精彩推荐