ARM 交叉编译时如何选择要链接的静态库?

2024-11-05 08:37:00
admin
原创
30
摘要:问题描述:我在 Ubuntu 中有一个 ARM 交叉编译器(arm-linux-gnueabi-gcc),默认架构是 ARMv7。但是,我想编译 ARMv5 二进制文件。我通过为编译器提供选项来实现这一点-march=armv5te。到目前为止一切顺利。由于我的 ARM 系统使用 BusyBox,因此我必须以...

问题描述:

我在 Ubuntu 中有一个 ARM 交叉编译器(arm-linux-gnueabi-gcc),默认架构是 ARMv7。但是,我想编译 ARMv5 二进制文件。我通过为编译器提供选项来实现这一点-march=armv5te

到目前为止一切顺利。由于我的 ARM 系统使用 BusyBox,因此我必须以静态链接方式编译二进制文件。因此我给了 gcc 这个-static选项。

但是,链接器链接到我的 ARMv5 二进制文件的libc.a存在问题。此文件使用 ARMv7 架构选项进行编译。因此,即使我将 ARM 二进制文件与 ARMv5 进行交叉编译,也无法在基于 BusyBox 的 ARMv5 机器上运行它。

  1. 我该如何解决这个问题?

  2. 我可以在哪里获得 ARMv5 libc.a静态库,以及如何链接它?

先感谢您。


解决方案 1:

你有两个选择,

  1. 获取正确的编译器。

  2. 编写您自己的“C”库。

获取正确的编译器。

让编译器与您的系统匹配总是最安全的。这适用于 x86 Linux 和各种发行版。如果不同的编译器可以工作,您就很幸运了。交叉编译时会更加困难,因为编译器通常不会自动同步。尝试在 2014 年的 Ubuntu 系统上运行在 1999 年 x86 Mandrake Linux 上编译的程序。

除了指令兼容性(您已确定)之外,还有 ABI 和 OS 依赖关系。具体来说,armv7最有可能是硬浮点(具有浮点 FPU和寄存器调用约定),而您需要软浮点(模拟 FPU)。特定的glibc(或ucLibc)具有 Linux OS 的特定调用和期望。例如,线程的工作方式随着时间的推移而发生了变化。

编写自己的

您始终可以使用-fno-builtin-ffreestanding以及-static。然后您不能使用任何libc函数,但您可以自己对它们进行编程。

有外部源代码,如Mark Martinec 的 snprintfwrite()和易于实现的构建块,

#define _SYS_IOCTL_H 1
#include <linux/unistd.h>
#include <linux/ioctl.h>
static inline int write(int fd, void *buf, int len)
{
    int rval;
        asm volatile ("mov      r0, %1
    "
                "mov    r1, %2
    "
                "mov    r2, %3
    "
                "mov    r7, %4
    "
                "swi    #0
    "
                "mov    %0, r0
    "
                : "=r" (rval)
                : "r" (fd),
                  "r" (buf),
                  "r" (len),
                  "Ir" (__NR_write)
                : "r0", "r1", "r2", "r7");
    return rval;
}

static inline void exit(int status)
{
        asm volatile ("mov      r0, %0
    "
                "mov    r7, %1
    "
                "swi    #0
    "
                : : "r" (status),
                  "Ir" (__NR_exit)
                : "r0", "r7");
}

你必须添加你自己的启动机制,由“C”库来负责,

/* Called from assembler startup. */
int main (int argc, char*argv[])
{
    write(STDOUT, "Hello world
", sizeof("Hello world
"));
    return 0;
}

/* Wrapper for main return code. */
void __attribute__ ((unused)) estart (int argc, char*argv[])
{
    int rval = main(argc,argv);
    exit(rval);
}

/* Setup arguments for estart [like main()]. */
void __attribute__ ((naked)) _start (void)
{
    asm(" sub     lr, lr, lr
"   /* Clear the link register. */
        " ldr     r0, [sp]
"     /* Get argc... */
        " add     r1, sp, #4
"   /* ... and argv ... */
        " b       estart
"       /* Let's go! */
        );
}

如果这太令人生畏,因为您需要实现很多功能,那么您可以尝试获取各种库源并用它们重建-fno-builtin,并确保这些库不会与不兼容的 Ubuntu 库链接。

像crosstool-ng这样的项目可以让你构建一个适合armv5系统的正确编译器(可能具有更高级的代码生成功能)。这似乎很麻烦,但上述替代方案也不容易。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用