How to cross-compile with GNU autotools for armv5tel? - gcc

I have an ARM machine that runs Linux (BusyBox).
# uname -a
# Linux XXXXXXXX 2.6.28 #1 PREEMPT Fri Sep 26 22:47:38 UTC 2014 armv5tel GNU/Linux
I've cross-compiled a simple program on my Ubuntu 32-bit desktop:
./configure --host=arm-linux-gnueabi LDFLAGS="-static"
make
But when I try to run it on the ARM machine, it gives me Segmentation Fault error.
Program is super simple:
#include <stdio.h>
int main()
{
printf("Hello, World!");
return 0;
}
Here are a few things I've already tried/checked:
I've checked md5 hashes on both machines to eliminate the possibility that something went wrong at the time of copying an executable over the network
Stripped the executable with arm-linux-gnueabi-strip. I was comparing my executable with another executable that was already in the target machine with file:
# file my_program
# my_program: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.31, BuildID[sha1]=0x4b1f2773e54b141d5157b86f0f10438a372625c9, stripped
# file their_program
# their_program: ELF 32-bit LSB executable, ARM, version 1 (GNU/Linux), statically linked, stripped
What am I doing wrong?

Apparently my cross-compile toolchain was not the right one.
I ended up using crosstool-ng. Btw it's very simple to use and a great tool, all you have to do is to choose the right toolchain for your device.
I have built an arm-unknown-linux-uclibcgnueabi toolchain with crosstool-ng, which solved my problem.

Related

How to use constants created with .equ in a second assembler file?

Context
I'm working through some examples in a book by Johnathan Bartlett titled "Learn to Program with Assembly" (2021). The author assumes a linux environment. I'm on OSX (Monterey). He's using gcc. I've got clang (v 13.1.6). In chapter 7 the author introduces laying out data records.
To facilitate this, he uses the .equ directive to define some constants in a file titled persondata.s which happens to only contain a data segment. For example:
# Describe the components of the struct
.globl WEIGHT_OFFSET, HAIR_OFFSET, HEIGHT_OFFSET, AGE_OFFSET .equ WEIGHT_OFFSET, 0
.equ HAIR_OFFSET, 8
.equ HEIGHT_OFFSET, 16
.equ AGE_OFFSET, 24
In another file, tallest.s, he makes use of the HEIGHT_OFFSET constant to access the height of a person record. This file has only a text segment.
movq HEIGHT_OFFSET(%rbx), %rax
The Problem
When I assemble tallest.s using the built-in tools on OSX, the assembler complains that I'm trying to use 32-bit absolute addressing in 64-bit mode.
The Question
How is this supposed to work on OSX? How am I supposed to make use of .equ defined constants?
Things I Tried
If I merge these two files into one file, then assembler doesn't complain. It treats HEIGHT_OFFSET as the constant that it is.
I presume the idea is to have constants defined along with the data, and then make use of those constants in code to avoid 'magic numbers'. Sounds like a good idea.
I tried assembling, linking, and running this code using the book's docker image (johnnyb61820/linux-assembly). It works. No complaints. Some details
# as -v
GNU assembler version 2.31.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.31.1
^C
# ld -v
GNU ld (GNU Binutils for Debian) 2.31.1
# uname -a
Linux eded2adb9c06 5.10.124-linuxkit #1 SMP Thu Jun 30 08:19:10 UTC 2022 x86_64 GNU/Linux
So it works as written under that set-up. Just not under my set-up which is clang (v 13.1.6).
Based on the fact that this works in the linuxkit docker image, I thought to install gcc via homebrew on my machine. This got me version 12.2.0 of gcc, which I used to try and compile/link my files. It also thinks HEIGHT_OFFSET is a problem due to 32-bit absolute addressing in 64-bit mode.
Based on the output of name -a in the docker image, I'm guessing it is 64 bit. Linux eded2adb9c06 5.10.124-linuxkit #1 SMP Thu Jun 30 08:19:10 UTC 2022 x86_64 GNU/Linux
Oddly enough, it doesn't complain about 32-bit absolute addressing not being supported. Under OSX, I had to make everything rip-relative to access any static-data (true for both gcc and clang). Makes me wonder what it is doing with these addresses.
As a possibly final note, under OSX yasm also doesn't like me using .equ defined constants from another file. It complains about wanting to make use of "32 bit absolute relocations" in 64 bit mode. GCC (12.2.0) and llvm-mc (13.0.1) also take issue with the HEIGHT_OFFSET constant.

Cross-compile to ARMv7 failed

I try to compile a go program on my Linux desktop (Linux desktop 4.10.0-28-generic #32-Ubuntu SMP Fri Jun 30 05:32:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux), go version go version go1.8.3 linux/amd64 to arm:
$ GOPATH=/home/xrfang/git/hermes/ GOARM=7 GOARCH=arm go build .
the executable is generated, but seems NOT ARMv7:
$ file hermes
hermes: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
It shows EABI5. How can I cross-compile to ARMv7? Is there anything missing on my Linux Desktop so that the cross-compile fallback to a lower ARM version?
Thanks.
I believe, it is not ARMv5. I was trying to do the same on MAC OS and 'file' command on Mac is saying v7, but the 'file' command on Linux don't. However, I do know that v7 has some good improvements and may boost the performance of your program.
But, that is out of scope of this question and you may need to dig deeper into what you're doing and why a performance improvement is expected.
All I can say is, it is compiled for v7.

How can I build zaptel for ARM?

I'm trying to cross-compile zaptel driver for Arm
I'm following this project http://svn.astfin.org/software/baps/trunk to build zaptel driver for blackfin arch. After building uClinux, oslec and patching zaptel.patch to build extra modules wcfxs, sport_interface, bfsi instead of original one, this command does the magic
make -C /home/working/BAPS/uClinux-dist/linux-2.6.x/ SUBDIRS=/home/working/BAPS/zaptel-1.4.3/ modules V=1 ARCH=blackfin CROSS_COMPILE=bfin-uclinux- EXTRA_CFLAGS="-DCONFIG_4FX_SPI_INTERFACE"
Build process run successfully, bfsi.ko, sport_interface.ko, wcfxs.ko, zaptel.ko generated and useful for my astfin board (well, also the oslec.ko in the previous process).
bfsi.ko: ELF 32-bit LSB relocatable, Analog Devices Blackfin, version 1 (SYSV), not stripped
sport_interface.ko: ELF 32-bit LSB relocatable, Analog Devices Blackfin, version 1 (SYSV), not stripped
wcfxs.ko: ELF 32-bit LSB relocatable, Analog Devices Blackfin, version 1 (SYSV), not stripped
zaptel.ko: ELF 32-bit LSB relocatable, Analog Devices Blackfin, version 1 (SYSV), not stripped
So then I want to do the same thing with my arm board (particularly my Beaglebone Black).
Firstly, I completely built BBB Kernel, and then the oslec. I know oslec is also a kernel module but I easily built it.
make -C [my bbb kernel] ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- EXTRA_CFLAGS="-I/home/working/AAPS/oslec/kernel -I/home/working/AAPS/oslec/spandsp-0.0.3/src/spandsp" SUBDIRS=/home/working/AAPS/oslec/kernel modules
I have the oslec.ko and it looks ok.
kernel/oslec.ko: ELF 32-bit LSB relocatable, ARM, version 1 (SYSV), not stripped
But I got stuck in the final step - building zaptel
Here's my make command
make -C /home/working/AAPS/dl/buildroot-bbb/output/build/linux-3.8.13/\
SUBDIRS=/home/working/AAPS/zaptel-1.4.3/ modules V=1 ARCH=arm\
CROSS_COMPILE=arm-linux-gnueabihf- KBUILD_NOPEDANTIC=1\
EXTRA_CFLAGS="-DCONFIG_4FX_SPORT_INTERFACE -I/home/working/AAPS/zaptel-1.4.3/staging/usr/include "
come with error:
include/linux/wait.h:159:47: error: ‘TASK_INTERRUPTIBLE’ undeclared (first use in this function)
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
I figured out that the constant TASK_INTERRUPTIBLE was defined in $(my_bbb_kernel)/include/linux/sched.h and $(blackfin_uclinux_kernel)/linux-2.6.x/include/linux/sched.h, but one works (uclinux for blackfin) and one does not (my bbb kernel). I dont know how can they included cause i'm not so familiar with linux kernel module development.
So if anyone have any idea in this case, please give me some instructions or explains.
Best Regards
Loi Dang

w_scan cross compile issue

I download the w_scan project(a small command line utility used to perform frequency scans for DVB and ATSC transmissions.) from http://wirbel.htpc-forum.de/w_scan/index_en.html. I also install gcc-arm-linux-gnueabi on my Ubuntu x86_64. I use the ./configure --host=arm-linux CC=arm-linux-gnueabi-gcc command to cross-compile, and it generates a binary file. However, I copy that file to my target board and execute that file, it shows sh: ./w_scan: No such file or directory.
I use the file command to see information of that binary file, it shows ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0x9a584b4720fadf5eb5b77034ac85092daeb728c9, not stripped.
I found that error message stands the configuration of cross-compile doesn't correct.(reference http://ubuntuforums.org/showthread.php?t=1141792). How can I fix my configuration and correct cross-compile that project, THANKS!
./configure --host=arm-linux CC=arm-linux-gnueabi-gcc
make CFLAGS=-static
copy that binary file to my target board, it can execute normally and successfully.
And the file w_scan will shows
ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.31, BuildID[sha1]=0x67b7e9f93015607f891c0b77493d9e47059ef6a1, not stripped.

bash: ./mips-linux-gnu-gcc: cannot execute binary file error

I've recently installed a mips-linux-gnu-gcc crosstool in my linux machine which is based on i686. When I want to compile some codes, it showed me that error.
Every installing step was followed by http://developer.mips.com/tools/compilers/open-source-toolchain-linux/
After I installed the crosstool, I wrote a simple helloworld C file like this:
#include<stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
But when I run:
/mips-linux-gnu-gcc hello.c -o hello -static
The compiler just print error:
bash: ./mips-linux-gnu-gcc: cannot execute binary file
I'm wondering maybe I've made some mistakes in some steps, but I can't figure it out.
Maybe some of you can help me, I'm confused by the problem.
The compiler you downloaded from MIPS is a 64-bit executable. Are you running a 32-bit host?
If you need a cross compiler for a 32-bit host targeting MIPS GNU/Linux, consider using the Sourcery CodeBench Lite compiler for MIPS GNU/Linux targets:
Sourcery CodeBench Lite for MIPS GNU/Linux
The link to the Sourcery CodeBench tools above comes from the MIPS pages just one level up from the link you provided:
MIPS Compilers Page
It looks like the mips-linux-gnu-gcc binary does not match the architecture of the machine you are trying to run it on. This might be something like a 32/64 bit mismatch.
Try using the free Mentor/Codesourcery MIPS gnu/gcc cross compilation tool chain instead. You can download from here.

Resources