I'm trying to make custom binaries for initrd for x86 system. I took generic precompiled Debian 7 gcc (version 4.7.2-5) and compiled kernel with it. Next step was to make helloworld program instead of init script in initrd to check my development progress. Helloworld program was also compiled with that gcc. When I tried to start my custom system, kernel started with no problem, but helloworld program encountered some errors:
kernel: init[24879] general protection ip:7fd7271585e0 sp:7fff1ef55070 error:0 in init[7fd727142000+20000]
(numbers are not mine, I took similar string from google). Helloworld program:
#include <stdio.h>
int main(){
printf("Helloworld\r\n");
sleep(9999999);
return 0;
}
Compilation:
gcc -static -o init test.c
Earlier I also had stuck with same problem on ARM system (took generic compiler, compiled kernel and some binaries with it and tried to run, kernel runs, but binary - not). Solved it with complete buildroot system, and took buildroot compiler in next projects.
So my question is: what difference between gcc compiled as part of buildroot and generic precompiled gcc?
I know that buildroot compiler is made in several steps, with differenet libs and so on, is this main difference, platform independence?
I don't need a solution, I can take buildroot anytime. I want to know source of my problem, to avoid such problems in future. Thanks.
UPD: Replaced sleep with while(1); and got same situation. My kernel output:
init[1]: general protection ip: 8053682 sp: bf978294 error: 0 in init[8048000+81000]
printk: 14300820 message suppressed.
and repeating every second.
UPD2: I added vdso32-int80.so (original name, like in kernel tree), tested - no luck.
I added ld-linux.so (2 files: ld-2.13.so with symbolic link), tested - same error.
Busybox way allows to run binaries without any of this libraries, tested by me on ARM platform.
Thanks for trying to help me, any other ideas?
Related
I'm trying to compile a source code which was originally written for FreeBSD and since strlcpy isn't included in the linux GlibC , I'm now stopped at this stage.
GCC has suggested that I can use strncpy but I don't want to actually change the source code.
Do I need to re-compile my LibC ?
Any help is appreciated.
The best solution to port BSD applications is libbsd; and it's already packaged for most systems.
On Debian-based systems the development package is named libbsd-dev.
You can compile unmodified BSD source code by adding the following to your CFLAGS:
-DLIBBSD_OVERLAY -I/usr/include/bsd, and linking with -lbsd.
However, instead of hardcoding those values, you should use pkg-config with the libbsd-overlay package if you intend to distribute your build system.
You can download source code from https://github.com/freebsd/freebsd/blob/master/sys/libkern/strlcpy.c and add it with 2 modifications to your source code:
$ diff strlcpy.c strlcpy.c.orig
20c20
< //__FBSDID("$FreeBSD$");
---
> __FBSDID("$FreeBSD$");
23c23
< //#include <sys/libkern.h>
---
> #include <sys/libkern.h>
I have compiled successfully this function with gcc 7.5.0 on Ubuntu 18.04.
I have a prepared a minimal Cmake project containing one cpp file which represent the main and one cpp file which represent the shared library, that prints basically hello world.
https://github.com/courteous/wasmELF.git
The target is to compile this miniaml code with emscripten/clang only and produce
1) one WebAssembly (wasm) binary module version 0x1 (MVP)
2) one ELF 64-bit LSB
without clearing the cmake build directory and rebuilding it again.
Currently i can successfully produce them bought by running the commands
emconfigure cmake ../ -DCMAKE_BUILD_TYPE=WASM
make
and
cmake ../ -DCMAKE_BUILD_TYPE=Linux
make
However the problem is that in order to do that i need to compile the first one with Clang the to remove the build and then to do a second compilation with GCC. I would like Emscripten/Clang to produce them bought instead. I do not want to delete the build directory since the compilation times is taking too long. (Well not in this Project but imagine if the project was much larger)
What i see is that emscripten/clang selects always a target "wasm32-unknown-emscripten"
clang++ -target wasm32-unknown-emscripten
and if i understand that correctly the target should change
I do see that the project is producing LLVM IR bitcode since i have send the flag "flto"
i.e.
file TestSharedClass.cpp.o
TestSharedClass.cpp.o: LLVM IR bitcode
and in the CMakeLists.txt
set(CMAKE_CXX_FLAGS "-flto")
x86_64-unknown-linux-gnu is a supported target by emscripten/Clang
~/Projects/emscripten/emsdk/upstream/bin$ ./llc --version
LLVM (http://llvm.org/):
LLVM version 11.0.0git
Optimized build with assertions.
Default target: x86_64-unknown-linux-gnu
Host CPU: haswell
Registered Targets:
wasm32 - WebAssembly 32-bit
wasm64 - WebAssembly 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
In cmake i do have
SET(TARGET x86_64-unknown-linux-gnu)
however when i run
emconfigure cmake ../ -DCMAKE_BUILD_TYPE=Linux
make
i get mainTestFile.js and mainTestFile.wasm instead of ELF 64-bitcode.
what i am doing wrong here. How to tell clang to product once ELF and once wasm from the same code run without having to clear the build directory. This should be possible since clang is producing LLVM IR bitcode. Or do i understand that wrong?
https://github.com/emscripten-core/emscripten/issues/10361
OK that seems to not be possible i.e. the reply from the dev on github states that emcc or emmake can not be used with another target other then wasm32-unknown-emscripten.
I need to build a complete linux development framework for a Cortex-M MCU, specifically a STM32F7 Cortex-M7. First I've to explain some background info so please bear with me.
I've downloaded and built a gcc toolchain with croostool-ng 1.24 specifying an armv7e-m architecture with thumb-only instructions and linux 4.20 as the OS and that I want the output to be FLAT executables (I assumed it will mean bFLT).
Then I proceeded to compile the linux kernel (version 4.20) using configs/stm32_defconf, and then a statically compiled busybox rootfs, all using my new toolchain.
Kernel booted just fine but throw me an error and kernel painc with the following message:
Starting init: /sbin/init exists but couldn't execute it (error -8)
and
request_module: modprobe binfmt-464c cannot be processed, kmod busy with 50 threads
The interesting part is the last message. My busybox excutable turned out to be an .ELF! Cortex-M has no MMU, so it's imposible to build a linux kernel on a MMU-less architecture with .ELF support, that's why an (464c)"LF" binary loader can't be found, there is none.
So at last, my question is:
how could I build bFLT executables to run on MMU-less Linux architectures? My toolchain has elf2flt, but in crosstool-ng I've already specified a MMU-less architecture and FLAT binary and I was expecting direct bFLT output, not a "useless" executable. Is that even possible?
Or better: is there anywhere a documented standard procedure to build a complete, working Linux system based on Cortex-M?
Follow-up:
I gave up on building FLAT binaries and tried FDPIC executables. Another dead end. AFAIK:
Linux has long been supporting ELF FDPIC, but the ABI for ARM is pretty new.
It seems that still at this day and age, GCC has not a standard way to enable FDPIC. On some architectures you can use -mfdpic. Not on arm, don't know why. I even don't know if ARM FDPIC is supported at all by mainline GCC. Info is extremely scarce if inexistent.
It seems crosstool-ng 1.24 is BROKEN at building ARM ELF FDPIC support. Resulting gcc has not -mfdpic, and -fPIC generates ARM executables, not ARM FDPIC.
Any insight will be very appreciated.
you can generate FDPIC ELF files just with a prebuilt arm-linux-gnueabi-gcc compiler.
Specifications of an FDPIC ELF file:
Position independent executable/code (i.e. -fPIE and fPIC)
Should be compiled as a shared executable (ET_DYN ELF) to be position independent
use these flags to compile your programs:
arm-linux-gnueabi-gcc -shared -fPIE -fPIC <YOUR PROGRAM.C> -o <OUTPUT FILE>
I've compiled busybox successfully for STM32H7 with this method.
As I know, unfortunately FDPIC ELFs should be compiled with - shared flag so, they use shared libraries and cannot be compiled as -static ELF.
For more information take a look at this file:
https://github.com/torvalds/linux/blob/master/fs/binfmt_elf_fdpic.c
Track the crosstool-ng BFLAT issue from here:
https://github.com/crosstool-ng/crosstool-ng/issues/1399
Can we configure gcc running on intel x64 architecture to produce binary for ARM chip by just passing some flags to gcc and not using a cross compiler.
Short: Nope
Compiler:
gcc is not a native crosscompiler, the target architecture has to be specified at the time you compile gcc. (Some exceptions apply, as for example x86 and x86_64 can be supported at the same time)
clang would be a native crosscompiler, and you can generate code for arm by passing -target=arm-linux-gnu, but you still cant produce binaries, as you need a linker and a C-library too. Means you can run clang -target=arm-linux-gnu -c <your file> and compile C/C++ Code (will likely need to point it to your C/C++ include paths) - but you cant build binaries.
Rest of the toolchain:
You need a fitting linker and toolchain too, both are specific to the architecture and OS you want to run at.
Possible solutions:
Get a fitting toolchain, or compile your own. For arm linux you have for ex. CrossToolchains if you are on debian, for barebones you can get a crosscompiler from codesourcery.
Since you were very vague, its not possible to give you a clearer answer
I'm uing ARM_EABI cross-compiler to compile a code that makes use of pthreads to run at an ARM Cortex A9 simulation.
While I'm able to compile it with no problems (just as I've did with others non-pthread applications, which ran fine in the simulation), I'm having an error message when trying to run my pthread application at the simulated ARM (which is running Linux as OS). It's the following:
./pttest.exe: /lib/libpthread.so.0: no version information available (required by ./pttest.exe)
I did my research and found out that's because it's a dynamic lib, and I'm compiling the application with a higher version than the one available on my simulator.
My question is: how to find force my cross-compiler to compile the application with the same pthread lib version of my simulator? Is there anywhere I can download different versions of pthreads? And how to set it?
Sorry, I'm quite a newbie in that area.
Try compiling your application statically, e.g.
gcc -static -o myapplication myapplication.c