Baremetal长凳和软件

问题描述 投票:1回答:2

我正在寻找有关裸机编程的一些信息。我正在不同的Powerpc平台上工作,当前正在尝试证明某些测试不受linux内核的影响。这些测试是非常基本的测试,并且加载并存储在asm volatile中,也包含一些基准测试(Coremark,Dhrystone等)。这些测试可以完美地在Linux上运行,但是我现在必须在裸机上进行测试,而我实际上并没有经验。我所有的平台都安装了u-boot,我想知道是否有这样的应用程序可以让我以交叉编译的方式运行测试powerpc-eabi?例如,由u-boot启动的gdbserver是否可以通过串行端口或以太网进行通信? U-boot可能有一个busybox吗?

embedded-linux powerpc bare-metal
2个回答
3
投票

Uboot是一个引导程序...使用它。您可能有一个带有uboot的xmodem下载器或ymodem下载器,如果需要推送,您可以将您的程序转换为一长串向内存写入的字,然后分支到该程序。

uboot将已经设置了ram和串行端口,无论如何,这就是您正在与uboot进行通讯的方式,因此您不必做所有这些事情。您不需要配置串行端口,但是您将想了解如何写一个字符,这意味着轮询状态寄存器以使发送器寄存器为空,然后将一个字符写入发送寄存器。对字符串中的每个字符或要打印的内容重复以上操作。

假设您的C程序是C的引导程序,通常至少需要设置堆栈指针(运行了btw uboot,所以堆栈已经设置好了,只要您这样加载程序,您就不能这样做)不会与uboot的行为冲突),然后跳转到C入口点。

取决于您编写高级语言程序的方式(我假设是C),那么您可能必须将.bss区域清零并设置.data区域,这是关于使用引导加载程序将程序复制到ram的好处。只需运行它,您通常就不需要执行任何操作,下载并运行的二进制文件已经将bss清零并且将.data放在正确的位置。因此,由于您甚至不必设置堆栈,因此可以重新设置堆栈并分支或仅分支。

构建裸机程序是真正的挑战,因为您没有可以进行系统调用的系统,而这是很难放弃和/或模拟的。例如,newlib使操作变得容易一些,因为它很容易替换系统后端,因此您可以例如将printfs保留在dhrystone中(与删除它们并根据需要找到不同的输出字符串或输出结果的方法。) >

编译为C文件的对象很容易,组装程序也很容易,并且您应该能够使用powerpc-eabi gcc交叉编译器来做到这一点,下一个挑战是链接,告诉链接器内容在哪里。因为这可能只是一块简单的RAM,所以您可以执行-Ttext 0x123450000之类的操作,其中数字是您要使用的RAM的基址。如果您有任何乘法或除法,浮点数或任何其他gcc库函数(用于替换您的处理器可能执行或可能不会执行的操作或需要包装程序来正确执行的操作),或任何libc调用,它将尝试将它们链接到理想情况下,gcc库很容易,但是取决于交叉编译器,它们可能是一个挑战,最坏的情况是采用gcc源代码并自己构建这些函数,或者获取或构建具有不同目标选项的其他gcc交叉编译器(通常很容易要做)。

我强烈建议您反汇编二进制文件,并确保引导程序的入口点是否在二进制文件的开头。使用objcopy生成二进制文件powerpc -...- objcopy myprog.elf -O二进制myprog.bin。然后在uboot提示符上使用xmodem或ymodem复制该程序并运行它。

备份。从零件的数据表中查找uart并找出基址时,应首先使用uboot提示符写入uart发送寄存器的地址,例如,向该地址写入0x30,并且如果您具有正确的地址然后在您的命令之后再次打印uboot提示符之前,输出中应该有一个额外的零“ 0”。如果您无法通过uboot命令行执行一次写入操作就可以做到这一点,那么您将无法在任何类型的程序中使用该地址,即地址错误或执行其他错误操作。

然后用汇编语言编写一个非常小的程序,该程序通过写入该地址将字符输出到uart,然后根据处理器的速度将其计数为一个大数字。如果您以100Mhz的速度运行,则计数到1亿或更多(或从几亿计数到零),然后跳转到开头并重复,输出,等待输出,等待。构建并链接这个小程序,然后使用xmodem或其他下载并分支到该程序。如果您无法让它每隔几秒钟输出一个字符,那么您将无法进行更复杂的操作。

[下一个小程序,轮询状态寄存器,等待tx缓冲区为空,然后将0x30写入tx寄存器。将保存0x30的寄存器递增到0x31,然后将该寄存器递增0x37。跳转到等待tx为空并输出新值0x31,使其成为无限循环。如果一旦开始运行,您将看不到01234567012345670 ...永远重复,而数字不会被弄乱,它们必须是0-7并重复,那么您将无法进行更复杂的操作。

用分支到C入口点的小引导程序重复C中的最后两个程序,如果您无法使这些工作正常进行,则将无法继续进行。

从任何您认为您不能没有的库调用(例如,printf)开始,如果您不能进行简单的printf(“ Hello World \ n”);与所有的链接和系统后端一起使用,那么您将无法运行Dhrystone并保留其系统调用。

编译器可能会将一些Dhrystone转换为您将要实现的memcpy或memset调用,最有可能手动调整了这些版本的汇编版本,并且您的Dhrystone性能数字可能并且将受到此类功能的实现的极大影响。 ,所以您不能简单地执行此操作

void memset ( unsigned char *d unsigned char c, unsigned int len)
{
    while(len--) *(d++)=c;
}

并期待任何表现。您很可能可以获取这些版本的gcc lib或gnu libc版本,或者只是从这些测试之一的linux构建中窃取这些版本(反汇编并获取asm),这样您就可以将苹果变成苹果...

基准测试通常比真实情况更虚假,在相同的环境(Linux或裸机等)上使用相同的编译器获取相同的基准测试源非常容易,并且通过做各种简单的事情,不同的方法会显示出截然不同的结果。编译器选项,重新排列功能,在引导程序中添加一些nops等。用于构建不同代码或利用cahce或受到其损害的任何方法,等等。如果要显示裸机比在操作系统上更快,如果不花点时间,就不会发生。您将需要提高i和d缓存的速度,d缓存可能需要提高mmu的速度,依此类推。这些全都是研究项目。然后,您需要知道如何控制编译器的构建,确保已启用优化,如前所述,在引导程序中添加或删除nops来更改代码中紧密循环相对于缓存行的对齐方式。在操作系统上有中断和正在发生的事情,可能您正在执行多任务处理,因此使用裸机,您应该能够使dhrystone等测试以与linux相同或更快的速度运行,如果不能,那不是因为linux更快这是因为您在裸机实现中没有做正确的事情。

是的,您可能可以使用gdb与uboot对话并加载程序,不确定我从不使用gdb,我更喜欢使用哑终端和x或y调制解调器,或者将jtag与openocd终端一起使用(将telnet转换为openocd而不是gdb, )。


0
投票

您可以尝试将基准与u-boot一起编译。这样,在u-boot完成加载后,它将加载您的程序。我知道这对于ARM平台是可能的。我不知道是否存在用于PowerPC裸机开发的工具链

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.