What is the "linux-2.6.3x.x/include/asm-generic/' for? - linux

My os-book says that if you want to add a system call to the Linux kernel, edit the linux-2.x/include/asm-i386/unistd.h.
But the linux kernel's source structure seems to change a lot. In the linux-2.6.34.1 version kernel source tree, I only find a linux-2.6.34.1/include/asm-generic/unistd.h and linux-2.6.34.1/arch/x86/include/asm/unistd.h.
It seems that editing the latter one make more sense.
My question is what the /inlcude/asm-generic is for? How can asm related code be generic?

asm-generic is a generic versions of functions usually coded in assembly, but coded in plain C, without any inline assembly. It's probably made for easy porting of the kernel to new platforms, and to keep platfom-independent common code in one place.

Related

Convert object file to another architecture

I am trying to use a Wifi-Dongle with a Raspberry Pi. The vendor of the dongle provides a Linux driver that I can compile successfully on the ARM-architecture, however, one object file, that comes with the driver, was precompiled for a x86-architecture, which causes the linker to fail.
I know it would be much easier to compile that (quite big) file again, but I don't have access to the source code.
Is it possible to convert that object file from a x86-architecture to an ARM-architecture?
Thank you!
Um, no, it looks to me like a waste of time. Wi-Fi driver is complex, and you say this one troublesome object file is 'large'. Lots of pain to translate, and chance of successful debug slim to none. Also, any parameter passing between this one object file and the rest of the system would not translate directly between x86 and ARM.
In theory, yes. Doing it on a real kernel driver without access to source code will be difficult.
If you had high quality dis-assembly of the object file, and the code in the object file is "well behaved" (using standard calling conventions, no self modifying code) then you could automatically translate the X86 instructions into arm instructions. However, you probably don't have high quality dis-assembly. In particular, there can be portions of the object file that you will not be able to properly classify as code or data doing normal recursive descent dis-assembly. If you misinterpret data as code, it will be translated to ARM code, rather than copied as is, and so will have the wrong values. That will likely cause the code to not work correctly.
Even if you get lucky, and can properly classify all of the addresses in the object file, there are several issues that will trip you up:
The calling conventions on X86 are different than the calling conventions on ARM. This means you will have to identify patterns related to X86 calling conventions and change them to use ARM calling conventions. This is a non trivial rewrite.
The hardware interface on ARM is different than on X86. You will have to understand how the driver works in order to translate the code. That would require either a substantial X86 hardware comparability layer, or reverse engineering of how the driver works. If you can reverse engineer the driver, then you don't need to translate it. You could just write an arm version.
The internal kernel APIS are different between ARM and X86. You will have to understand those difference and how to translate between them. That's likely non trivial.
The Linux Kernel uses an "alternatives" mechanism, which will rewrite machine code dynamically when code is first loaded into the kernel. For example, on uni-processor machines, locks are often replaced with no-ops to improve perf. Instructions like "popcnt" are replaced with function calls on machines that don't support it, etc. It's use in the Kernel is extremely common. This means there's a good chance the code in the object is file is not "well behaved", according to the definition given above. You would have to either verify that the object file doesn't use that mechanism, or find a way to translate uses of it.
X86 uses a different memory model than ARM does. To "safely" translate X86 code to ARM (without introducing race conditions) you would have to introduce memory fences after every memory access. That would result in REALLY BAD performance on an ARM chip. Figuring out when you need to introduce memory fences (without doing it everywhere) is an EXTREMELY hard problem. The most successful attempts at that sort of analysis require custom type systems, which you won't have in the object file.
Your best bet (quickest route to success) would be to try and reverse engineer what the object file in question does, and then just replace it.
There is no reasonable way of doing this. Contact the manufacturer and ask if they can provide the relevant code in ARM code, as x86 is useless to you. If they are not able to do that, you'll have to find a different supplier of either the hardware [that has an ARM version, or fully open source, of all the components], or supplier of the software [assuming there is another source of that].
You could translate the x86 assembly manually by installing x86 GNU binutils and disassemble
the object file with objdump. Probably some addresses will differ but should be straight forward.
Yes, you could most definitely do a static binary translation. x86 disassembly is painful though, if this was compiled from high level then it isnt as bad as it could be.
Is it really worth the effort? Might try an instruction set simulator instead. Have you done an analysis of the number of instructions used? System calls required, etc?
How far have you gotten so far on the disassembly?
Maybe the file only contains a binary dump of the wifi firmware? If so you need no instruction translation and a conversion can be done using objcopy.
You can you use objdump -x file.o and look if any real executable code is inside the obj-file or if it's only data.
If you have access to IDA with Hex-Rays decompiler, you can (with some work) decompile the object file into C code and then try to recompile it for ARM.

compiling user space code in linux

A very basic question to which I could not find an answer by searching on the internet.
Basically, I want to know:
how the compiler differentiates a user space code from the kernel space code?
Is the makefile differnt for compiling user space code compared to kernel space code ?
Best regards,
Kutty
The compiler just follows flags you pass to it, the rest is as usual and nothing magic.
For a small example, look at Writing Your Own Loadable Kernel Module. See also Modules vs. Program.
The difference is of course in how those modules and programs are treated by the OS and which permissions they have (see also rings).

Linux equivalent header for synch.h

I have a C code which contains #include<synch.h> The code compiles successfully in solaris but in Linux I find that the header is missing.
As suggested in a few links, can "sync.h" be used instead?
Or is there any other equivalent header for synch.h in Linux?
The synch.h header in Solaris is for Solaris threads. Among other things, it provides declarations for semaphores and mutexes. You can either this library (http://sctl.sourceforge.net/sctl_v1.1_rn.html) to give you Solaris compatible threading on Linux or, a much better idea, rework your code to use POSIX threading.
We can't be sure, but one likely possibility is that this is the synch.h that's part of NACHOS, which is often used in educational environments. Head over to the NACHOS project page and read up on it, and decide whether you think that's probably the right thing; if so, you can download and install it for free.

Producing executables within Linux (in relation to implementing a compiler)

For my university, final-year dissertation, I am going to implement a compiler for a skeletal form of the C programming language, then go about extending it until it resembles something a little more like Java with array bounds checking, type-checking and so forth.
I am relatively competent at much of the theory that relates to compiler construction, and have experience programming in MIPS assembly language, so I do understand a little of what it is to write extremely low-level code.
My main concern is that I am likely to be able to get all the way to the point where I need to produce the actual machine-code output, but then not understand enough about how machine code is executed from the perspective of the operating system running it.
So, my actual question is basically, "does anyone know the best place to read up about writing assembly to run on an intel x86-64 processor under linux?"
The main gap in my knowledge is how the machine code is actually run in practise. Is it run directly on the processor, making "syscall"s (or the x86 equivalent) when it needs services provided by the kernel, or is the assembly language somehow an encapsulated description that tells the kernel how to execute the instructions (in a manner similar to an interpreted language such as Java)?
Any help you can provide would be greatly appreciated.
This document explains how you can implement a foreign function interface to interact with other code: http://www.x86-64.org/documentation/abi.pdf
Firstly, for the machine code start here: http://www.intel.com/products/processor/manuals/
Next, I assume your question about how the machine code is run is really about how the OS loads the exe into memory and calls main()? These links may help
Linkers and loaders:
http://www.linuxjournal.com/article/6463
ELF file format:
http://en.wikipedia.org/wiki/Executable_and_Linkable_Format and
http://www.linuxjournal.com/article/1060
Your machine code will go into the .text section of the executable
Finally, best of luck. Your project is similar to my final year project, except I targeted the JVM and compiled a subset of Visual Basic!

Linux user-space ELF loader

I need to do a rather unusual thing: manually execute an elf executable. I.e. load all sections into right places, query main() and call it (and cleanup then). Executable will be statically linked, so there will be no need to link libraries. I also control base address, so no worries about possible conflicts.
So, is there are any libraries for that?
I found OSKit and its liboskit_exec, but project seems to be dead since 2002.
I'm OK with taking parts of projects (respecting licenses, of course) and tailoring them to my need, but as I'm quite a noob in the linux world, I dont even know where to find those parts! :)
PS. I need that for ARM platform.
UPD Well, the matter of loading elfs seems to require some good knowledge about it (sigh), so I'm out to read some specs and manuals. And I think I will stick to bionic/linker and libelfsh. Thanks guys!
Summarized findings:
libelf: http://directory.fsf.org/project/libelf/
elfsh and libelfsh (are now part of eresi): http://www.eresi-project.org/
elfio (another elf library): http://sourceforge.net/projects/elfio/
OSKit and liboskit_exec (outdated): http://www.cs.utah.edu/flux/oskit/
bionic/linker: https://android.googlesource.com/platform/bionic
A quick apt-cache search suggests libelf1, libelfg0 and/or libelfsh0. I think the elfsh program (in the namesake package) might be an interesting practical example of how to use libelfsh0.
I haven't tried any myself, but I hope they might be helpful. Good luck :-)
Google's Android, in it's "bionic" libc implementation, has a completely reimplemented ELF loader. It's reasonably clean, and probably a better source than gilbc if you're looking for something simple.
Take a look at libelf for reading the executable format. You are going to have trouble with this I think.
Sounds like, as you don't need libraries for anything, why not just mmap your executable, set data about various memory areas and jmp/b in?
I don't know if ARM has an NX-bit equivalent, but worth checking.
This tool contains an ELF loader: http://bitwagon.com/rtldi/rtldi.html
I reused the code from rtldi for an ELF chainloader in another project. The code is here: http://svn.gna.org/viewcvs/plash/trunk/chroot-jail/elf-chainloader/?rev=877 and there is some background here: http://plash.beasts.org/wiki/Story16. (Apparently I have to break these links because stackoverflow won't let me post >1 link!)

Resources