277 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
Bionic comes with a set of 'clean' Linux kernel headers that can safely be
 | 
						|
included by userland applications and libraries without fear of hideous
 | 
						|
conflicts. for more information why this is needed, see the "RATIONALE"
 | 
						|
section at the end of this document.
 | 
						|
 | 
						|
these clean headers are automatically generated by several scripts located
 | 
						|
in the 'bionic/kernel/tools' directory, which process a set of original
 | 
						|
and unmodified kernel headers in order to get rid of many annoying
 | 
						|
declarations and constructs that usually result in compilation failure.
 | 
						|
 | 
						|
the 'clean headers' only contain type and macro definitions, with the
 | 
						|
exception of a couple static inline functions used for performance
 | 
						|
reason (e.g. optimized CPU-specific byte-swapping routines)
 | 
						|
 | 
						|
they can be included from C++, or when compiling code in strict ANSI mode.
 | 
						|
they can be also included before or after any Bionic C library header.
 | 
						|
 | 
						|
the generation process works as follows:
 | 
						|
 | 
						|
  * 'bionic/kernel/original/'
 | 
						|
    contains a set of kernel headers as normally found in the 'include'
 | 
						|
    directory of a normal Linux kernel source tree. note that this should
 | 
						|
    only contain the files that are really needed by Android (use
 | 
						|
    'find_headers.py' to find these automatically).
 | 
						|
 | 
						|
  * 'bionic/kernel/common'
 | 
						|
    contains the non-arch-specific clean headers and directories
 | 
						|
    (e.g. linux, asm-generic and mtd)
 | 
						|
 | 
						|
  *'bionic/kernel/arch-arm/'
 | 
						|
    contains the ARM-specific directory tree of clean headers.
 | 
						|
 | 
						|
  * 'bionic/kernel/arch-arm/asm'
 | 
						|
    contains the real ARM-specific headers
 | 
						|
 | 
						|
  * 'bionic/kernel/arch-x86'
 | 
						|
    similarly contains all headers and symlinks to be used on x86
 | 
						|
 | 
						|
  * 'bionic/kernel/tools' contains various Python and shell scripts used
 | 
						|
    to manage and re-generate the headers
 | 
						|
 | 
						|
the tools you can use are:
 | 
						|
 | 
						|
  * tools/find_users.py
 | 
						|
    scans a list of source files or directories and prints which ones do
 | 
						|
    include Linux headers.
 | 
						|
 | 
						|
  * tools/find_headers.py
 | 
						|
    scans a list of source files or directories and recursively finds all
 | 
						|
    the original kernel headers they need.
 | 
						|
 | 
						|
  * tools/clean_header.py
 | 
						|
    prints the clean version of a given kernel header. with the -u option,
 | 
						|
    this will also update the corresponding clean header file if its
 | 
						|
    content has changed. you can also process more than one file with -u
 | 
						|
 | 
						|
  * tools/update_all.py
 | 
						|
    automatically update all clean headers from the content of 
 | 
						|
    'bionic/kernel/original'. this is the script you're likely going to 
 | 
						|
    run whenever you update the original headers.
 | 
						|
 | 
						|
NOTE:
 | 
						|
  if ANDROID_PRODUCT_OUT is defined in your environment, both 'clean_header.py'
 | 
						|
  and 'update_all.py' will automatically issue "p4 add/edit/delete" commands
 | 
						|
  appropriately to reflect the changes being made.
 | 
						|
 | 
						|
  you will need to "p4 submit" manually though...
 | 
						|
 | 
						|
 | 
						|
HOW TO BUILD BIONIC AND OTHER PROGRAMS WITH THE CLEAN HEADERS:
 | 
						|
==============================================================
 | 
						|
 | 
						|
add bionic/kernel/common and bionic/kernel/arch-<yourarch> to your C
 | 
						|
include path. that should be enough. Note that Bionic will not compile properly 
 | 
						|
if you don't.
 | 
						|
 | 
						|
 | 
						|
HOW TO SUPPORT ANOTHER ARCHITECTURE:
 | 
						|
====================================
 | 
						|
 | 
						|
see the content of tools/defaults.py, you will need to make a few updates
 | 
						|
here:
 | 
						|
 | 
						|
  - add a new item to the 'kernel_archs' list of supported architectures
 | 
						|
 | 
						|
  - add a proper definition for 'kernel_known_<arch>_statics' with
 | 
						|
    relevant definitions.
 | 
						|
 | 
						|
  - update 'kernel_known_statics' to map "<arch>" to
 | 
						|
    'kernel_known_<arch>_statics'
 | 
						|
 | 
						|
then, add the new architecture-specific headers to original/asm-<arch>.
 | 
						|
(please ensure that these are really needed, e.g. with tools/find_headers.py)
 | 
						|
 | 
						|
finally, run tools/update_all.py
 | 
						|
 | 
						|
 | 
						|
 | 
						|
HOW TO UPDATE THE HEADERS WHEN NEEDED:
 | 
						|
======================================
 | 
						|
 | 
						|
IMPORTANT IMPORTANT:
 | 
						|
 | 
						|
  WHEN UPDATING THE HEADERS, ALWAYS CHECK THAT THE NEW CLEAN HEADERS DO
 | 
						|
  NOT BREAK THE KERNEL <-> USER ABI, FOR EXAMPLE BY CHANGING THE SIZE
 | 
						|
  OF A GIVEN TYPE. THIS TASK CANNOT BE EASILY AUTOMATED AT THE MOMENT
 | 
						|
 | 
						|
copy any updated kernel header into the corresponding location under
 | 
						|
'bionic/kernel/original'.
 | 
						|
 | 
						|
for any new kernel header you want to add, first run tools/find_headers.py to be
 | 
						|
sure that it is really needed by the Android sources. then add it to
 | 
						|
'bionic/kernel/original'
 | 
						|
 | 
						|
then, run tools/update_all.py to re-run the auto-cleaning
 | 
						|
 | 
						|
 | 
						|
 | 
						|
HOW THE CLEANUP PROCESS WORKS:
 | 
						|
==============================
 | 
						|
 | 
						|
this section describes the action performed by the cleanup program(s) when they
 | 
						|
process the original kernel headers into clean ones:
 | 
						|
 | 
						|
1. Optimize well-known macros (e.g. __KERNEL__, __KERNEL_STRICT_NAMES)
 | 
						|
 | 
						|
    this pass gets rid of everything that is guarded by a well-known macro
 | 
						|
    definition. this means that a block like
 | 
						|
 | 
						|
       #ifdef __KERNEL__
 | 
						|
       ....
 | 
						|
       #endif
 | 
						|
 | 
						|
    will be totally omitted from the output. the optimizer is smart enough to
 | 
						|
    handle all complex C-preprocessor conditional expression appropriately.
 | 
						|
    this means that, for example:
 | 
						|
 | 
						|
       #if defined(__KERNEL__) || defined(FOO)
 | 
						|
       ...
 | 
						|
       #endif
 | 
						|
 | 
						|
    will be transformed into:
 | 
						|
 | 
						|
       #ifdef FOO
 | 
						|
       ...
 | 
						|
       #endif
 | 
						|
 | 
						|
    see tools/defaults.py for the list of well-known macros used in this pass,
 | 
						|
    in case you need to update it in the future.
 | 
						|
 | 
						|
    note that this also remove any reference to a kernel-specific configuration
 | 
						|
    macro like CONFIG_FOO from the clean headers.
 | 
						|
 | 
						|
 | 
						|
2. remove variable and function declarations:
 | 
						|
 | 
						|
  this pass scans non-directive text and only keeps things that look like a
 | 
						|
  typedef/struct/union/enum declaration. this allows to get rid of any variable
 | 
						|
  or function declaration that should only be used within the kernel anyway
 | 
						|
  (and which normally *should* be guarded in a #ifdef __KERNEL__ ... #endif
 | 
						|
  block, if the kernel writers were not so messy)
 | 
						|
 | 
						|
  there are however a few exceptions: it is seldom useful to keep the definition
 | 
						|
  of some static inline functions performing very simple operations. a good
 | 
						|
  example is the optimized 32-bit byte-swap function found in
 | 
						|
  arch-arm/asm/byteorder.h
 | 
						|
 | 
						|
  the list of exceptions is in tools/defaults.py in case you need to update it
 | 
						|
  in the future.
 | 
						|
 | 
						|
  note that we do *not* remove macro definitions, including these macro that
 | 
						|
  perform a call to one of these kernel-header functions, or even define other
 | 
						|
  functions. we consider it safe since userland applications have no business
 | 
						|
  using them anyway.
 | 
						|
 | 
						|
 | 
						|
3. whitespace cleanup:
 | 
						|
 | 
						|
  the final pass remove any comments and empty lines from the final headers.
 | 
						|
 | 
						|
 | 
						|
4. add a standard disclaimer:
 | 
						|
 | 
						|
  prepended to each generated header, contains a message like
 | 
						|
  "do not edit directly - file was auto-generated by ...."
 | 
						|
 | 
						|
 | 
						|
RATIONALE:
 | 
						|
==========
 | 
						|
 | 
						|
OVERVIEW OF THE CURRENT KERNEL HEADER MESS:
 | 
						|
-------------------------------------------
 | 
						|
 | 
						|
The original kernel headers are not easily usable from userland applications.
 | 
						|
they contain many declarations and construct that will result in a compilation
 | 
						|
failure or even worse, incorrect behaviour. for example:
 | 
						|
 | 
						|
- some headers try to define Posix types (e.g. size_t, ssize_t) that can
 | 
						|
  conflict with the corresponding definitions provided by your C library.
 | 
						|
 | 
						|
- some headers use constructs that cannot be compiled in ANSI C mode.
 | 
						|
 | 
						|
- some headers use constructs do not compile with C++ at all.
 | 
						|
 | 
						|
- some headers contain invalid "legacy" definitions for the benefit of old
 | 
						|
  C libraries (e.g. glibc5) but result in incorrect behaviour if used
 | 
						|
  directly.
 | 
						|
 | 
						|
  e.g. gid_t being defined in <linux/types.h> as a 16-bit type while the
 | 
						|
  kernel uses 32-bit ids. this results in problems when getgroups() or
 | 
						|
  setgroups() are called, since they operate on gid_t arrays.
 | 
						|
 | 
						|
unfortunately, these headers are also the only source of some really extensive
 | 
						|
constant and type definitions that are required by userland applications.
 | 
						|
think any library/program that need to access ALSA, or Video4Linux, or
 | 
						|
anything related to a specific device or Linux-specific system interface
 | 
						|
(e.g. IOCTLS, etc...)
 | 
						|
 | 
						|
As a consequence, every Linux distribution provides a set of patched kernel
 | 
						|
headers to be used by userland applications (which installs in
 | 
						|
/usr/include/linux/, /usr/include/asm/, etc...). these are manually maintained
 | 
						|
by distribution packagers, and generated either manually or with various
 | 
						|
scripts. these headers are also tailored to GNU LibC and cannot be reused
 | 
						|
easily by Bionic.
 | 
						|
 | 
						|
for a really long period, the kernel authors have stated that they don't want
 | 
						|
to fix the problem, even when someone proposed a patch to start cleaning the
 | 
						|
official headers. from their point of view this is purely a library author
 | 
						|
problem.
 | 
						|
 | 
						|
fortunately, enlightnment happened, and the kernel now provides a way to
 | 
						|
install a set of "user-friendly" headers that are generated from the official
 | 
						|
ones by stripping the __KERNEL__ protected declarations.
 | 
						|
 | 
						|
unfortunately, this is not enough for Bionic because the result still contains
 | 
						|
a few broken declarations that are difficult to route around. (see below for
 | 
						|
a little bit of details).
 | 
						|
 | 
						|
we plan to be able to support these kernel-generated user-land headers in the
 | 
						|
future, but the priority on this issue is very low.
 | 
						|
 | 
						|
 | 
						|
WHAT WE DO:
 | 
						|
-----------
 | 
						|
 | 
						|
so we're doomed to repeat the same effort than anyone else. the big difference
 | 
						|
here is that we want to automate as much as possible the generation of the
 | 
						|
clean headers to easily support additional architectures in the future,
 | 
						|
and keep current with upstream changes in the header definitions with the
 | 
						|
least possible hassle.
 | 
						|
 | 
						|
of course, this is only a race to the bottom. the kernel maintainers still
 | 
						|
feel free to randomly break the structure of their headers (e.g. moving the
 | 
						|
location of some files) occasionally, so we'll need to keep up with that by
 | 
						|
updating our build script/original headers as these cases happen.
 | 
						|
 | 
						|
what we do is keep a set of "original" kernel headers, and process them
 | 
						|
automatically to generate a set of "clean" headers that can be used from
 | 
						|
userland and the C library.
 | 
						|
 | 
						|
note that the "original" headers can be tweaked a little to avoid some subtle
 | 
						|
issues. for example:
 | 
						|
 | 
						|
- when the location of various USB-related headers changes in the kernel
 | 
						|
  source tree, we want to keep them at the same location in our generated
 | 
						|
  headers (there is no reason to break the userland API for something
 | 
						|
  like that).
 | 
						|
 | 
						|
- sometimes, we prefer to take certain things out of blocks guarded by a
 | 
						|
  #ifdef __KERNEL__ .. #endif. for example, on recent kernels <linux/wireless.h>
 | 
						|
  only includes <linux/if.h> when in kernel mode. we make it available to
 | 
						|
  userland as well since some code out there assumes that this is the case.
 | 
						|
 | 
						|
- sometimes, the header is simply incorrect (e.g. it uses a type without
 | 
						|
  including the header that defines it before-hand)
 | 
						|
 |