裸机交叉编译器输入

发布于 2024-08-04 19:01:05 字数 473 浏览 2 评论 0原文

裸机交叉编译器的输入限制是什么...比如它不编译带有指针或 malloc 的程序...或者任何需要比底层硬件更多的东西...以及如何找到这些限制..

我还想问...我为目标mips构建了一个交叉编译器..我需要使用这个交叉编译器创建一个mips可执行文件...但我无法找到可执行文件在哪里...因为有 1 个可执行文件,我发现 mipsel-linux-cpp 应该编译、汇编和链接,然后生成 a.out 但它没有这样做...

但是 ./cc1 提供了一个 mips 程序集... ....

有一个安装文件夹,其中有一个 gcc 可执行文件,它使用 i386 程序集,然后给出一个 exe...我不明白当我将目标指定为 mips 时,gcc exe 如何给出 i386 而不是 mips 程序集... .

请帮助我真的无法理解发生了什么...

我按照以下步骤操作.. 1.安装binutils 2.19 2.为mips配置gcc..(g++,core)

What are the input limitations of a bare metal cross compiler...as in does it not compile programs with pointers or mallocs......or anything that would require more than the underlying hardware....also how can 1 find these limitations..

I also wanted to ask...I built a cross compiler for target mips..i need to create a mips executable using this cross compiler...but i am not able to find where the executable is...as in there is 1 executable which i found mipsel-linux-cpp which is supposed to compile,assemble and link and then produce a.out but it is not doing so...

However the ./cc1 gives a mips assembly.......

There is an install folder which has a gcc executable which uses i386 assembly and then gives an exe...i dont understand how can the gcc exe give i386 and not mips assembly when i have specified target as mips....

please help im really not able to understand what is happ...

I followed the foll steps..
1. Installed binutils 2.19
2. configured gcc for mips..(g++,core)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏日浅笑〃 2024-08-11 19:01:05

我建议您应该开始两个单独的问题。

GNU 工具链没有任何操作系统依赖性,但 GNU 库有。大多数 GCC 裸机交叉构建都使用 Newlib C 库,它提供了一组您必须自己映射到目标的系统调用存根。这些存根包括实现流 I/O 和堆管理所需的低级调用。根据您的需要,它们可以非常简单或非常复杂。如果唯一的 I/O 支持是 UART 到 stdin/stdout/stderr,那么这很简单。您不必实现所有内容,但如果您不实现 I/O 存根,则您将无法使用 printf() 等。如果您希望 malloc() 工作,则必须实现 sbrk()/sbrk_r() 系统调用。

GNU C++ 库将与 Newlib 作为其底层库一起正常工作。如果您使用 C++,C 运行时启动(通常是 crt0.s)必须包含静态初始化程序循环,以调用代码可能包含的任何静态对象的构造函数。运行时启动当然还必须初始化处理器、时钟、SDRAM控制器、定时器、MMU等;这是你的责任,而不是编译器的责任。

我没有 MIPS 目标的经验,但所有处理器的原理都是相同的,有一篇非常有用的文章,名为 “使用 GNU 构建裸机 ARM” 您可能会发现它很有帮助,其中大部分内容都是相关的 - 特别是移植有关实现 Newlib 存根的部分。

关于您的另一个问题,如果您的编译器名为 mipsel-linux-cpp,那么它不是“裸机”构建,而是 Linux 构建。此外,这个可执行文件并不是真正的“编译、汇编和链接”,而是一个分别调用预处理器、编译器、汇编器和链接器的驱动程序。必须正确配置它才能调用交叉工具而不是主机工具。我通常单独调用链接器,以便强制执行有关链接哪个标准库 (-nostdlib) 的决策,而且还因为当应用程序由多个执行单元组成时它更有意义。除此之外,我无法提供太多帮助,因为我一直使用由比我更有耐心的人构建的 GNU-ARM 工具,而且托管在 Windows 上,在 Windows 上调用主机工具链的可能性较小(一个我也避免使用那些依赖 Cygwin 的工具链的原因)

I would suggest that you should have started two separate questions.

The GNU toolchain does not have any OS dependencies, but the GNU library does. Most bare-metal cross builds of GCC use the Newlib C library which provides a set of syscall stubs that you must map to your target yourself. These stubs include low-level calls necessary to implement stream I/O and heap management. They can be very simple or very complex depending on your needs. If the only I/O support is to a UART to stdin/stdout/stderr, then it is simple. You don't have to implement everything, but if you do not implement teh I/O stubs, you won't be able to use printf() for example. You must implement the sbrk()/sbrk_r() syscall is you want malloc() to work.

The GNU C++ library will work correctly with Newlib as its underlying library. If you use C++, the C runtime start-up (usually crt0.s) must include the static initialiser loop to invoke the constructors of any static objects that your code may include. The run-time start-up must also of course initialise the processor, clocks, SDRAM controller, timers, MMU etc; that is your responsibility, not the compiler's.

I have no experience of MIPS targets, but the principles are the same for all processors, there is a very useful article called "Building Bare Metal ARM with GNU" which you may find helpful, much of it will be relevant - especially porting the parts regarding implementing Newlib stubs.

Regarding your other question, if your compiler is called mipsel-linux-cpp, then it is not a 'bare-metal' build but rather a Linux build. Also this executable does not really "compile, assemble and link", it is rather a driver that separately calls the pre-processor, compiler, assembler and linker. It has to be configured correctly to invoke the cross-tools rather than the host tools. I generally invoke the linker separately in order to enforce decisions about which standard library to link (-nostdlib), and also because it makes more sense when a application is comprised of multiple execution units. I cannot offer much help other than that here since I have always used GNU-ARM tools built by people with obviously more patience than me, and moreover hosted on Windows, where there is less possibility of the host tool-chain being invoked instead (one reason why I have also avoided those tool-chains that rely on Cygwin)

眼藏柔 2024-08-11 19:01:05

编辑
随着时间的推移,我重写了原来的答案,试图提供更有用的东西。

我无法为你的问题提供具体答案。我从未尝试过在 MIPS 机器上运行代码。我所拥有的是启动和运行各种“裸机”板的丰富经验。各种CPU以及各种编译器和交叉编译器。因此,我了解适用于所有此类情况的原则。我将指出您需要吸收哪些知识才能希望在这样的工作中取得成功,并希望我可以列出一些资源链接以帮助您开始学习这些知识。

我担心您不知道指针完全是裸机编译器可以处理的东西,它们是基本的机器原语。这告诉我,您可能不是一个陷入这种特定场景的专家嵌入式开发人员。没关系。嵌入式系统编程并没有什么神奇之处,您可以学习您需要了解的内容。

第一步是了解 C 语言和您希望运行代码的机器之间的关系。基本上C是一种可移植的汇编语言。这意味着 C 适合操纵机器的基本操作。从这个意义上说,机器的基本操作是读取和写入内存位置,对从内存读取的数据执行算术和布尔运算,并根据该数据做出分支和循环决策。特别是,C 语言中的指针概念允许您操作指定内存位置处的数据。

到目前为止一切都很好,但仅在内存中进行原始计算通常是不够的 - 您需要一种从内存输入和输出数据的方法。为此,您需要操作板上的硬件外围设备。如果硬件外设是内存映射的,那么用于控制外设的机器寄存器看起来就像内存位置一样,并且 C 可以直接操作它们。即使在这种情况下,更有可能的是,通过使用专门为此目的提供的例程库来扩展 C 核心语言,可以最好地处理有用的 I/O。这些库例程处理板上外围硬件操作所涉及的所有烦人的细节(定时器、中断、非内存映射 I/O),并用方便的 C 函数调用接口将它们包装起来。这个想法是你可以简单地 printf("hello world");库调用负责显示字符串的细节。

熟练的开发人员知道如何使现有 I/O 库适应新板,或者如何开发新的库例程以提供对非标准定制硬件的访问。培养这些技能的经典方法是从一些简单的东西开始,通常是输出设备的 LED 和输入设备的开关。编写一个程序,以可预测的方式向 LED 发出脉冲,或者读取开关并反映在 LED 上。当你第一次开始这项工作时,你将会感到非常满意。

好吧,我已经闲聊够了。是时候为你提供更多的学习资源了。好消息是,现在是了解硬件和软件之间的接口如何工作的最佳时机。有大量免费可用的代码和文档。如您所知,Stackoverflow 是一个很棒的资源。祝你好运!链接如下;

嵌入式系统概述

熟悉 C 语言是基础

为什么不在尝试真正的硬件之前让代码在模拟器上运行

另一个模拟环境

Linux 设备驱动程序 - 一个重叠的主题

另一本关于裸机编程的书

EDIT
With more time available, I have rewritten my original answer in an attempt to provide something more useful.

I cannot provide a specific answer for your question. I have never tried to get code running on a MIPS machine. What I do have is plenty of experience getting a variety of "bare metal" boards up and running. All kinds of CPUs and all kinds of compilers and cross compilers. So I have an understanding of the principles that apply in all such situations. I will point out the kind of knowledge you will need to absorb before you can hope to succeed with a job like this, and hopefully I can list some links to resources to get you started on learning that knowledge.

I am worried you don't know that pointers are exactly the kind of thing a bare metal compiler can handle, they are a basic machine primitive. This tells me you are probably not an expert embedded developer who is just stuck in this particular scenario. Never mind. There isn't anything magic about programming an embedded system, and you can learn what you need to know.

The first step is getting to understand the relationship between C and the machine you wish to run code on. Basically C is a portable assembly language. This means that C is good for manipulating the basic operations of the machine. In this sense the basic operations of the machine are reading and writing memory locations, performing arithmetic and boolean operations on the data read from memory, and making branching and looping decisions based on that data. In particular the C concept of pointers allows you to manipulate data at locations in memory that you specify.

So far so good, but just doing raw computations in memory is not usually enough - you need a way to input and output data from memory. To do that you need to manipulate the hardware peripherals on your board. If the hardware peripherals are memory mapped then the machine registers used to control the peripherals look exactly like memory locations and C can manipulate them directly. Even in that case though, it is much more likely that doing useful I/O is best handled by extending the C core language with a library of routines provided just for that purpose. These library routines handle all the nasty details (timers, interrupts, non-memory mapped I/O) involved in manipulating the peripheral hardware on the board, and wrap them up with a convenient C function call interface. The idea is that you can go simply printf("hello world"); and the library call take care of the details of displaying the string.

An appropriately skilled developer knows how to adapt an existing I/O library to a new board, or how to develop new library routines to provide access to non-standard custom hardware. The classic way to develop these skills is to start with something simple, usually a LED for an output device, and a switch for an input device. Write a program that pulses a LED in a predictable way, or reads a switch and reflects in on a LED. The first time you get this working will be hugely satisfying.

Okay I have rambled enough. It is time to provide some more resources for you to study. The good news is that there's never been a better time to learn how things work at the interface between hardware and software. There is a wealth of freely available code and docs. Stackoverflow is a great resource as you know. Good luck! Links follow;

Embedded systems overview

Knowing the C language well is fundamental

Why not get your code working on a simulator before you try real hardware

Another emulated environment

Linux device drivers - an overlapping subject

Another book about bare metal programming

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文