binfmt_misc - Teach the Linux kernel to do neat stuff
This is binfmt_misc - the generic 'wrapper'-binary handler!
WARNING: if you use recent kernel versions from Alan Cox (2.4.2acXX and later) or versions 2.4.13 and up you need to mount binfmt_misc using
mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
Please dont ask me for reasons - ask Alexander Viro who did this during the stable series.
Binfmt_misc provides the ability to register additional binary formats to the Kernel without compiling an additional module/kernel. Therefore binfmt_misc needs to know magic numbers at the beginning or the filename extension of the binary.
You can get a patch to include binfmt_misc into your Kernel here. There is a patch to 2.0.30, a patch to 2.0.33/34 and a patch to 2.0.35. Binfmt_misc is integrated to Kernel 2.1.43, so there is no need to get a patch for them, just upgrade to the latest (stable ) 2.1.xx Kernel.
Read Documentation/binfmt_misc.txt and Documentation/java.txt for more information on how to use binfmt_misc (or continue reading this page). The 'magic' behind binfmt_misc
binfmt_misc works as follows:
- it maintains a linked list of structs, that contain a description of a binary format, including a magic with size (or the filename extension), offset and mask, and the interpreter name.
- on request it invokes the given interpreter with the original program as argument, as binfmt_java and binfmt_em86 and binfmt_mz do.
- binfmt_misc does not define any default binary-formats, you have to register an additional binary-format via the /proc interface (see below).
The /proc interface of binfmt_misc
You can find the following binfmt_misc related files/directories below /proc/sys/fs/binfmt_misc:
To register a new binary format do an echo :name:type:offset:magic:mask:interpreter: > register with appropriate name (the name for the /proc-dir entry), offset (defaults to 0, if omitted), magic and mask (which can be omitted, defaults to all 0xff) and last but not least the interpreter that is to be invoked (for example and testing '/bin/echo'). Type can be 'M' for usual magic matching or 'E' for filename extension matching (give extension in place of magic).
If you do a cat status you will get the current status (enabled/disabled) of binfmt_misc. Change the status by echoing 0 (disables) or 1 (enables) or -1 (caution: clears all previously registered binary formats) to status. I.e. for example echo 0 > status to disable binfmt_misc (temporarily).
- name (where name is the name you gave to register)
This file does exact the same thing as status except its scope is limited to the actual binary format. By cating this file you also recieve information about the interpreter/magic, etc. of the binfmt.
Example usage of binfmt_misc (emulate binfmt_java):
cd /proc/sys/fs/binfmt_misc echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:' > register echo ':HTML:E::html::/usr/local/java/bin/appletviewer:' > register echo ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:' > register echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
These three lines add support for Java executables and Java applets (like binfmt_java, additionally recognising the .html extension with no need to put '<--applet>' to every applet file). You have to install the JDK amd the shell-script /usr/local/java/bin/javawrapper, too. It works around the brokeness of the Java filename handling. To add a Java binary, just make a link to the .class-file somewhere in the path.
For full featured wrapping of deeply nested class files you will have to use the wrapper script created by Colin Watson ([email protected]…) /usr/local/java/bin/javawrapper and the additionally needed little c-proggy javaclassname.c (just compile it and stick it to /usr/local/java/bin/). These C/Script combination handles nested classes properly by looking up the fq classname from the class file.
Configuration of binfmt_misc ideally takes place in one of your init scripts (see init manual to find out where they resist, usually /etc/rc.d/). This is my personal binfmt_misc configuration script, it gets called in /etc/rc/boot.local .