Creating ELF image - windows

I need to create an ELF image file from shared objects (.so files) and write it to another partition in Windows. Then open this partition in Linux and load the shared objects.
Does anybody know how to create an ELF image (a bundle of many shared objects) in Windows?

You can use Cygwin and try a suitable GCC cross-toolchain. Perhaps you'll have to build it yourself first (which is troublesome), but there it goes...
EDIT:
Okay, here you are:
A simplified one:
Building GCC cross compiler (from "Linux" to "Windows") -- the basic steps are the same as described there. You'll just need to ./configure it with relevant --host=... and --target=.... And oh! Don't forget to set the build root, since building "in the source tree" is not supported -- you'll just get stuck in errors if you try (I did...)
A killer one:
http://cygwin.wikia.com/wiki/How_to_install_a_newer_version_of_GCC#Build_and_Install_GCC -- a complete guide.

Nowadays Linux understands NTFS. At least, it should be able to read off it.
You can also use a flash stick formatted as FAT32 or NTFS as the shared storage.
You can also run Linux in a VM and set up FTP server on it and exchange files through it.
There're many ways of sharing data between different OSes.

Related

Study device driver source files?

I want to study the source files of some of the device drivers that are installed and loaded on either a raspberry pi(raspian), beaglebone(debian) or a my laptop(ubuntu).
My aim is to learn how to properly implement my own modules by studying the source files of some drivers that actually works.
I am particularly interested in drivers that communicates with actual hardware (USB, I2C, SPI, UART etc).
Can someone tell me how to find these sources? are they available in some particular folder i.e something like /usr/src/**** or do I have to download all of the kernel source files from a particular kernel release?
All advice's, opinions and recommendations are most appreciated.
p.s I have read "Linux Kernel Development 3rd edition" but please tell me if
you know any other free/open-source books on the subject.
Best regards
Henrik
Linux Source directory and description :
arch/ -
The arch sub-directory contains all of the architecture specific kernel code.
Example :
1. 'arch/arm/' will have your board related configuration file.
like 'arch/arm/mach-omap/' will have omap specific source code.
2. 'arch/arm/config' Generates a new kernel configuration with the
default answer being used for all options. The default values
are taken from a file located in the arch/$ARCH/defconfig
file,where $ARCH refers to the specific architecture for which
the kernel is being built.
3. arch/arm/boot have kernel zImage, dtb image after compilation.
block/ -
This folder holds code for block-device drivers. Block devices are devices that accept and send data in blocks. Data blocks are chunks of data instead of a continual stream.
crypto/ -
This folder contains the source code for many encryption algorithms.
example, “sha1_generic.c” is the file that contains the code for
the sha1 encryption algorithm.
Documentation/ -
It has kernel related information in text format.
drivers/ - All of the system's device drivers live in this directory. They are further sub-divided into classes of device driver.
Example,
1. drivers/video/backlight/ has blacklight driver source which
will control display brightness.
2. drivers/video/display/ has display driver source.
3. drivers/input/ has input driver source code. like touch,
keyboard and mouse driver.
4. drivers/char/ has charter driver source code.
5. drivers/i2c/ has i2c subsystem and driver source code.
6. drivers/pci/ has pci subsytem and driver related source code.
7. drivers/bluetooth has Bluetooth driver file.
8. drivers/power has power and battery driver.
firmware/ -
The firmware folder contains code that allows the computer to read and understand signals from devices. For illustration, a webcam manages its own hardware, but the computer must understand the signals that the webcam is sending the computer.
fs/ -
All of the file system code. This is further sub-divided into directories, one per supported file system, for example vfat and ext2.
kernel/ -
The code in this folder controls the kernel itself. For instance, if a debugger needed to trace an issue, the kernel would use code that originated from source files in this folder to inform the debugger of all of the actions that the kernel performs. There is also code here for keeping track of time. In the kernel folder is a directory titled "power". Some code in this folder provide the abilities for the computer to restart, power-off, and suspend.
net/ -
net
The kernel's networking code.
lib
This directory contains the kernel's library code. The architecture specific library code can be found in arch/*/lib/.
scripts
This directory contains the scripts (for example awk and tk scripts) that are used when the kernel is configured.
lib/ -
This directory contains the kernel's library code. The architecture specific library code can be found in arch/*/lib/.
scripts/ -
This directory contains the scripts (for example awk and tk scripts) that are used when the kernel is configured.
mm/ -
This directory contains all of the memory management code. The architecture specific memory management code lives down in arch/*/mm/, for example arch/i386/mm/fault.c.
ipc/ -
This directory contains the kernels inter-process communications code.
**init/ -**The init folder has code that deals with the startup of the kernel (INITiation). The main.c file is the core of the kernel. This is the main source code file the connects all of the other files.
sound/ - This is where all of the sound card drivers are.
There are few more directory certs, crypto, security, include, virt and usr etc....
There are a few different methods that I use for viewing kernel related source, and I'm sure there are a few other good methods out there as well. You will find that the methods are largely the same.
Head on over to kernel.org and download the kernel of your choice. You will find driver related source under /<path to your downloaded kernel>/drivers. For example, I have downloaded and extracted kernel 4.5.5 to /usr/src/linux-4.5.5, and access the source for my drivers via /usr/src/linux-4.5.5/drivers.
Use a linux cross-reference website. Personally, I use the one hosted on free-electrons. These websites are nice for their free-text or identifier searches.
Browse Linus Torvalds' linux repo hosted on github.
Never mind, I found the source files under
~/linux/drivers/
example:
nano ~/linux/drivers/spi/spi-bitbang.c
Sorry, for any inconvenience!

Changing linux kernel system call number

I wanted to build my own custom kernel with a different syscall table. (same syscalls but in different position/numbers)
I was working on kernel 3.2.29.
Changing the kernel was quite easy:
1) changing the syscall position in ‫‪arch/x86/kernel/syscall_table_32.S‬‬
2) changing the syscall macro number in arch/x86/include/asm/unistd_32.h
3) compiling and installing the new kernel
I switched the syscalls around: sys_open took the place and number of sys_read, and vice versa.
I figured that if I compile glibc with the modified kernel headers, I could have a running system, but unfortunately, it wasn't enough and my system won't boot.
Am I missing something? What else do I need to do in order to have a running system?
The steps I have taken are:
1) building and installing the kernel as described in my question
2) extracting the new kernel headers using make headers_install INSTALL_HDR_PATH=[path]
3) building glibc with the parameter --with-headers=[path/include]
4) I used a live cd to access the file system externally in order to install the new glibc, using the make install install_root=[the original file system] (so the system won't break during the install)
I hope that the new glibc was built properly, but I am not sure.
After that, when booting the system, the boot stops in the (initrafms) shell screen:
I guess I need to rebuild the initrd, but how do I compile it according to the new syscall table?
You will have to rebuild everything. Even if all your binaries are dynamically linked, it is possible that the old syscalls were inlined into the binary because many of the C functions are just return syscall(__NR_somecall,...).
You could do this manually, but it could be difficult to keep the toolchains straight unless you use a cross compilable toolchain like buildroot, aboriginal or similar. Pick whichever best suits you (I prefer Rob Landley's aboriginal - http://landley.net/aboriginal/ )
Then to make your initrd just expand the old one using {z,bz,xz}cat oldinit.rd |cpio -id; rm oldinit.rd. Replace the old kernel modules, libs and binaries with the new and cpio and compress it back (cpio needs the -H newc option) ... or now you can rebuild your kernel and point the initramfs to that directory, but wouldn't recommend that if your initrd may need changed frequently such as if for instance you were testing out a whole new syscall structure and having to debug a lot.
Scrambling the system call numbers is really going to hurt. You'll at least need to rebuild all of the statically linked binaries on your system and your initrd (if you use one).
You haven't said at what point the boot fails, but even if the kernel comes up it is likely that the critical programs contained in the initrd compressed ramdisk would fail because they have the original syscall numbers hard-coded. You will need to rebuild and repackage those as well.
You might consider first replacing init with a static hello-world type of program to verify that your kernel can support a userspace at all; then look into the details of making all the complexity of a modern linux userspace match.
you had to learn to reading the messsage of pansic dump and show us what kenrel panic. Without this information, people can hardly help you or provide you useful suggestion.

cc1plus: error: include: Value too large for defined data type when compiling with g++

I am making a project that should compile on Windows and Linux. I have made the project in Visual Studio and then made a makefile for linux. I created all the files in Windows with VS.
It compiles and runs perfectly in VS but when I run the makefile and it runs g++ I get
$ g++ -c -I include -o obj/Linux_x86/Server.obj src/Server.cpp
cc1plus: error: include: Value too large for defined data type
cc1plus: error: src/Server.cpp: Value too large for defined data type
The code is nothing more than a Hello World atm. I just wanted to make sure that everything was working before I started development. I have tried searching but to no avail.
Any help would be appreciated.
I have found a solution on Ubuntu at least. I, like you have noticed that the error only occurs on mounted samba shares - it seems to come from g++ 'stat'ing the file, the inode returns a very large value.
When mounting the share add ,nounix,noserverino to the options, ie:
mount -t cifs -o user=me,pass=secret,nounix,noserverino //server/share /mount
I found the info at http://bbs.archlinux.org/viewtopic.php?id=85999
I had similar problem. I compiled a project in a CIFS mounted samba share. With one Linux kernel the compilation was done, but using an other Linux kernel (2.6.32.5), I got similar error message: "Value too large for defined data type". When I used the proposed "nounix,noserverino" CIFS mounting option, the problem was fixed. So in that case there is a problem with CIFS mounting, so the error message is misleading, as there are no big files.
GNU Core Utils:
27 Value too large for defined data type
It means that your version of the utilities were not compiled with
large file support enabled. The GNU utilities do support large files
if they are compiled to do so. You may want to compile them again and
make sure that large file support is enabled. This support is
automatically configured by autoconf on most systems. But it is
possible that on your particular system it could not determine how to
do that and therefore autoconf concluded that your system did not
support large files.
The message "Value too large for defined data type" is a system error
message reported when an operation on a large file is attempted using
a non-large file data type. Large files are defined as anything larger
than a signed 32-bit integer, or stated differently, larger than 2GB.
Many system calls that deal with files return values in a "long int"
data type. On 32-bit hardware a long int is 32-bits and therefore this
imposes a 2GB limit on the size of files. When this was invented that
was HUGE and it was hard to conceive of needing anything that large.
Time has passed and files can be much larger today. On native 64-bit
systems the file size limit is usually 2GB * 2GB. Which we will again
think is huge.
On a 32-bit system with a 32-bit "long int" you find that you can't
make it any bigger and also maintain compatibility with previous
programs. Changing that would break many things! But many systems make
it possible to switch into a new program mode which rewrites all of
the file operations into a 64-bit program model. Instead of "long"
they use a new data type called "off_t" which is constructed to be
64-bits in size. Program source code must be written to use the off_t
data type instead of the long data type. This is typically done by
defining -D_FILE_OFFSET_BITS=64 or some such. It is system dependent.
Once done and once switched into this new mode most programs will
support large files just fine.
See the next question if you have inadvertently created a large file
and now need some way to deal with it.
12 years after this question was posted, I get the same error, when building my c++ project in docker on ubuntu 20.04 in Windows 11 WSL2 using an old 32-bit compiler (gcc-linaro-arm-linux-gnueabi-2012.01-20120125_linux/bin/arm-linux-gnueabi-g++).
The issue is related to mounting of the windows filesystem into WSL, where we get 64 bit inodes, not supported by the old 32 bit toolchain, see also The 64 bit inode problem
As a quick workaround you can build if you move your project into the home folder of the ubuntu.
An alternative solution is to replace the stat() with LD_PRELOAD as described in Build on Windows 10 with WSL, section "Fix stat in 32-bit binaries". This shall be done in the docker image. To compile inode64.c I had to additionally add 32 bit header files with
sudo apt-get install gcc-multilib
If you are on mergerfs filesystem, removing use_ino option will solve the issue: https://github.com/trapexit/mergerfs/issues/485
I think your g++ parameters are a bit off, or conflicting.
-c compile only
-I directory of your includes (just plain include might be ambiguous. Try full path)
-o outfile (but -c says compile only)

Does a cross-platfrom compiler that can compile a native executable that can be run both in linux windows exist? Could it exist?

I remember a few years ago(2002) there was a multipartite virus that could be run natively on linux and windows. I don't know if a compiler could be specially craft an executable so that it could be read as both ELF and PE, so that the os would start executing at different entry points. Or a program that could merge two programs, one compiled using mingw, one compiled in native linux, to one program.
I don't know if such a program exists, or could it exist, and I'm know this could be implemented in Java or some scripting language, but that's not a native program.
Imagine the possibilities, I could deploy a program with linux and window (and perhaps os/x)libraries, and one main executable that could be run on any os. The cross-platform support would compensate the bigger size.
Windows programs have a DOS stub in the beginning, and I just ran an ELF executable through debug.com, which said that the first instruction of this exe was JG 0x147. Just maybe something could be done with this...
No.
Windows and Linux use vastly different binary file formats. See Portable Executable (Windows) and Executable and Linkable Format (Linux).
Something like WINE will run Windows executables on Linux but that's not the same thing.
This is actually a really terrible idea for multiple reasons.
Cross-compiling across operating system boundaries is extremely difficult to do properly.
If you go for the second route (building separate PE binaries on Windows and ELF on Linux, and then somehow merging them) you have to maintain two machines, each running a different OS and the full build stack, and you'd have to make sure that you tested both versions separately before gluing them together.
Dynamic linking is already a pain to properly manage, on Windows and on Linux; static linking can generate binaries that are much more inconvenient to deal with than whatever imaginary benefits you get from providing one single file type to your end-user.
If you want to run the same binary executable file on multiple OSes, your options are Java, Mono, and potentially NativeClient, the browser plug-in Google's developing to work around the "webapps are too slow" problem.

How to use OpenEmbedded generated images

I installed openembedded and tried building a couple of images for Zaurus SL-6000 "Tosa", basically, helloworld-image and console-image. And I ended up with an angstrom-dev/deploy/glibc/images/tosa directory that contains files like this (slightly truncated from a forum post I made elsewhere):
Angstrom-helloworld-image-glibc-ipk-2009.X-test-20090529-tosa-installkit.tgz
Angstrom-helloworld-image-glibc-ipk-2009.X-test-20090529-tosa.rootfs.jffs2
Angstrom-helloworld-image-glibc-ipk-2009.X-test-20090529-tosa.rootfs.tar.bz2
Angstrom-helloworld-image-glibc-ipk-2009.X-test-20090529-tosa.rootfs.tar.gz
helloworld-image-tosa.tar.bz2
helloworld-image-tosa.tar.gz
initramfs-kexecboot-image-tosa.cpio.gz
initramfs-kexecboot-image-tosa.jffs2
initramfs-kexecboot-image-tosa.tar.bz2
initramfs-kexecboot-image-tosa.tar.gz
modules-2.6.29-r0-tosa.tgz
updater.sh.tosa
zImage-2.6.29-r0-tosa.bin
zImage-kexecboot-2.6.24-r0-tosa.bin
zImage-kexecboot-tosa.bin
zImage-tosa.bin
I have no idea what all these do or how to install them properly. What I did try is various combinations of flashing a zImage.bin and initrd.bin using option 4 of the maintenance menu (as specified per earlier instructions). The flashing usually works alright but then when it boots, it loads a bootloader that cannot find any bootable devices. On a hunch, I tried unpacking one of the tar.gz images to an ext2 formatted SD card and tried booting with that plugged in and it was detected by the bootloader. Booting it sort of worked but it quickly exited back to the bootloader (I assume that was just a problem with the image I unpacked).
My questions are:
What is the correct usage for all of these file types, i.e. should the .jffs2 files be renamed initrd.bin and included in the flashing process? What am I supposed to do with the bz2 and gz files? Are they only for unpacking to external media?
How do I install to the internal flash? It used to work with the stable Angstrom 2007-12 build and instructions.
Is there a newer version of updater.sh (that one was not built by oe and I added it myself having picked it up from elsewhere)? The reason I ask is that when trying to flash zImage-2.6.29-r0-tosa.bin it fails during the update program with the error that the file is too big. That kernel is approximately 1.3mb while the others are 1.2mb. Is this a constraint of the SL-6000 itself? I thought it has 32mb of internal memory.
Unfortunately, none of the available documentation that I could find online talks about installing these files. I did find a small entry in the "Angstrom Manual" which talks about what they are but not how to use them as they are all device specific. Unfortunately the tosa documentation only talks about copying the files from an installkit and flashing the device from the maintenance menu.
Okay, "ant" over at OE forums was able to answer my questions ^^ Just recording the answer here for posterity.
installkit-tosa.tar.gz, contains updater.sh and zImage (the kexecboot-kernel). This kexecboot-kernel can be and is likely different from the kernel you will have on the rootfs after the machine boots. Unpack the installkit on a formatted card and follow the flashing procedure for the device.
Regarding the also be various image-rootfs.tar.gz, .bz2, and .jffs2 files. These are the root file systems that will be be booted by kexecboot. The tar.gz or .bz2 archive should be unpacked onto an ext2 (or possibly ext3) formatted SD or CF card. It will be detected by kexecboot at boot time and appear in the kexecboot menu.
If you want a rootfs in nand (installed internally), rename your-image-rootfs.jffs2 to initrd.bin and copy it on the card with updater.sh (then flash).

Resources