by September 6, 2001 0 comments

You are no longer restricted to native executable file formats (ELF,
a.out, etc), in
Linux. With kernel 2.2 onwards, there’s support for multiple file formats, that is,
you can make the kernel recognize any file format provided you’ve an interpreter for
it. These files can then be run just by typing their name at the prompt, like any pure
executable. You could, for instance, associate all text files with the vi editor.
Whenever you type the name of a text file on the shell prompt, the vi editor will
automatically load with this file.


Around the time of kernel 2.0 (yes, in Linux circles, you can use kernel version
numbers instead of dates as a new update comes up practically every day), the kernel had
binary support for Java classes. You had to tell the kernel in which directory the Java
runtime environment resided, and from then on you could run a Java class file right off
the shell prompt, just by typing its name instead of “java

If this could be done with Java, why not with other file formats? It was a simple
generalization, and by kernel 2.2, they had “miscellaneous binary format
support”. Just tell the kernel what interpreter to run for which binary (such as, the
Java runtime for Java class files), and you could add support for countless binary
formats. And since you are specifying the interpreter, it is not even necessary that the
file “run” as a binary does. It can even be something simpler like viewing text
files in an editor, in which case the editor would be specified as the interpreter.

Getting the kernel ready

To use this feature, you need a kernel with support for miscellaneous binaries. To
check if your kernel already has miscellaneous binary support compiled in, type “%
cat /proc/sys/fs/binfmt_misc/status”.

If the file has the word “enabled”, then your kernel does have support for
miscellaneous binaries. Otherwise, you’ll have to get the 2.2 kernel source
(it’s available on the March PCQ CD) and recompile the kernel, this time making sure
that “kernel support for MISC binaries” under “General setup” is

Running DOS and Windows files in Linux

If you have WINE (a Windows
emulator for *nix) installed, you can

register Windows executables
as a file type in Linux. These files then run seamlessly–right off the prompt.

We’ll use magic numbers
for identification. The magic number for EXE files is the string, MZ. To register it,

% cd /proc/sys/fs/binfmt_misc

% echo
‘:DOSWin:M::MZ::/usr/local/bin/wine:’ > register

That’s it. So if you have Windows
Solitaire, go ahead and run sol.exe!

Registering a binary format

The kernel has two ways of identifying a file as being of a particular binary format:

Magic numbers

A sequence of bytes that occur near the beginning of a binary file, and is unique for
every binary format. To identify a binary using this method, you must know the offset from
the beginning of the file from where the magic number begins, and what exactly the magic
number is. A good place to find out is “/usr/share/magic” and the
“magic” man page.

File name extensions

A simpler alternative is to identify a file format by its filename extension. While
this saves you from the hassle of finding out magic numbers, using magic numbers for
identification has the advantage that a file will be recognized even if it doesn’t
have the proper extension.

Every binary format that you want to use must be registered with the kernel, that is,
the kernel must be told how to identify the file format, and what interpreter to use for
it. This is done using the
“/proc/sys/fs/binfmt_misc/register” file.

To register a file format, echo a string of the form:

interpreter: to /proc/sys/fs/binfmt_ misc/register.

The fields are:

name The name by which this format will be identified.

type The method to use for recognizing the file format. This is “M”
for magic number, or “E” for extension.

offset Offset in bytes from the beginning of the file to the position where the
magic pattern begins.

magic The magic number, if you’re using magic numbers for recognition, or
the file extension otherwise.

mask Mask with which the magic number is bitwise ended. This defaults to all 1s.

interpreter The full path name of the program which should be invoked with the
name of the binary as the first argument. Remember that you’ve to be in root to register file formats.

Let’s start with a simple example of text files. Let’s say we want to
register all the files with the TXT extension as binary files, to be interpreted by the
editor vi (or any other editor for that matter).

To do this, simply type at the prompt (in the rest of this article, lines beginning
with % are typed at the prompt):

% cd /proc/sys/fs/binfmt_misc
% echo ":text:E::txt::/bin/vi:" > register

That’s all! The first field—text—is
the name that we give to this format. "E" indicates that recognition will be by
file extension. The next field is empty because we’re not using magic numbers in this
case. The extension is TXT, without the dot. And finally, "/bin/vi" is the
program which will be invoked when you "execute" a text file.

Now you’ll find a new file in /proc/sys/fs/binfmt_misc called "text".
This happens for every binary format registered. That file will have something like:

interpreter /bin/vi
extension .txt

To test your new file format, make the file, say,
foo.txt, executable with "% chmod +x foo.txt".

Then at the prompt type "% ./foo.txt". This should bring up foo.txt in vi.

An example with magic numbers

Now let’s have some more fun, and register the JPEG image format, so that we can
view one in XV just by making it executable, and typing it’s name at the prompt.
We’ll use magic numbers this time. The magic number for JPEG images is ffd8 (in
hexadecimal). Registering it is easy:

% cd /proc/sys/fs/binfmt_misc
% echo ":jpeg_img:M::\xff\xd8::/usr/X11R6/bin/xv:" > register

Now you should have a new file called
"jpeg_img" in /proc/sys/binfmt_misc, which should look like:

interpreter /usr/X11R6/bin/xv
offset 0
magic ffd8

To get back to where it all began, Java classes, you
can register that too. But I won’t explain that here. It’s done in the kernel
documentation. Look at /usr/src/linux/Documentation/java.txt.

Next time we’ll see how to write a small wrapper, a shell script to tweak things a
bit before actually calling the interpreter.

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.