162306a36Sopenharmony_ci=======================
262306a36Sopenharmony_ciEarly userspace support
362306a36Sopenharmony_ci=======================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciLast update: 2004-12-20 tlh
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci"Early userspace" is a set of libraries and programs that provide
962306a36Sopenharmony_civarious pieces of functionality that are important enough to be
1062306a36Sopenharmony_ciavailable while a Linux kernel is coming up, but that don't need to be
1162306a36Sopenharmony_cirun inside the kernel itself.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciIt consists of several major infrastructure components:
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci- gen_init_cpio, a program that builds a cpio-format archive
1662306a36Sopenharmony_ci  containing a root filesystem image.  This archive is compressed, and
1762306a36Sopenharmony_ci  the compressed image is linked into the kernel image.
1862306a36Sopenharmony_ci- initramfs, a chunk of code that unpacks the compressed cpio image
1962306a36Sopenharmony_ci  midway through the kernel boot process.
2062306a36Sopenharmony_ci- klibc, a userspace C library, currently packaged separately, that is
2162306a36Sopenharmony_ci  optimized for correctness and small size.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciThe cpio file format used by initramfs is the "newc" (aka "cpio -H newc")
2462306a36Sopenharmony_ciformat, and is documented in the file "buffer-format.txt".  There are
2562306a36Sopenharmony_citwo ways to add an early userspace image: specify an existing cpio
2662306a36Sopenharmony_ciarchive to be used as the image or have the kernel build process build
2762306a36Sopenharmony_cithe image from specifications.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciCPIO ARCHIVE method
3062306a36Sopenharmony_ci-------------------
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciYou can create a cpio archive that contains the early userspace image.
3362306a36Sopenharmony_ciYour cpio archive should be specified in CONFIG_INITRAMFS_SOURCE and it
3462306a36Sopenharmony_ciwill be used directly.  Only a single cpio file may be specified in
3562306a36Sopenharmony_ciCONFIG_INITRAMFS_SOURCE and directory and file names are not allowed in
3662306a36Sopenharmony_cicombination with a cpio archive.
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciIMAGE BUILDING method
3962306a36Sopenharmony_ci---------------------
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciThe kernel build process can also build an early userspace image from
4262306a36Sopenharmony_cisource parts rather than supplying a cpio archive.  This method provides
4362306a36Sopenharmony_cia way to create images with root-owned files even though the image was
4462306a36Sopenharmony_cibuilt by an unprivileged user.
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ciThe image is specified as one or more sources in
4762306a36Sopenharmony_ciCONFIG_INITRAMFS_SOURCE.  Sources can be either directories or files -
4862306a36Sopenharmony_cicpio archives are *not* allowed when building from sources.
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciA source directory will have it and all of its contents packaged.  The
5162306a36Sopenharmony_cispecified directory name will be mapped to '/'.  When packaging a
5262306a36Sopenharmony_cidirectory, limited user and group ID translation can be performed.
5362306a36Sopenharmony_ciINITRAMFS_ROOT_UID can be set to a user ID that needs to be mapped to
5462306a36Sopenharmony_ciuser root (0).  INITRAMFS_ROOT_GID can be set to a group ID that needs
5562306a36Sopenharmony_cito be mapped to group root (0).
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciA source file must be directives in the format required by the
5862306a36Sopenharmony_ciusr/gen_init_cpio utility (run 'usr/gen_init_cpio -h' to get the
5962306a36Sopenharmony_cifile format).  The directives in the file will be passed directly to
6062306a36Sopenharmony_ciusr/gen_init_cpio.
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ciWhen a combination of directories and files are specified then the
6362306a36Sopenharmony_ciinitramfs image will be an aggregate of all of them.  In this way a user
6462306a36Sopenharmony_cican create a 'root-image' directory and install all files into it.
6562306a36Sopenharmony_ciBecause device-special files cannot be created by a unprivileged user,
6662306a36Sopenharmony_cispecial files can be listed in a 'root-files' file.  Both 'root-image'
6762306a36Sopenharmony_ciand 'root-files' can be listed in CONFIG_INITRAMFS_SOURCE and a complete
6862306a36Sopenharmony_ciearly userspace image can be built by an unprivileged user.
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciAs a technical note, when directories and files are specified, the
7162306a36Sopenharmony_cientire CONFIG_INITRAMFS_SOURCE is passed to
7262306a36Sopenharmony_ciusr/gen_initramfs.sh.  This means that CONFIG_INITRAMFS_SOURCE
7362306a36Sopenharmony_cican really be interpreted as any legal argument to
7462306a36Sopenharmony_cigen_initramfs.sh.  If a directory is specified as an argument then
7562306a36Sopenharmony_cithe contents are scanned, uid/gid translation is performed, and
7662306a36Sopenharmony_ciusr/gen_init_cpio file directives are output.  If a directory is
7762306a36Sopenharmony_cispecified as an argument to usr/gen_initramfs.sh then the
7862306a36Sopenharmony_cicontents of the file are simply copied to the output.  All of the output
7962306a36Sopenharmony_cidirectives from directory scanning and file contents copying are
8062306a36Sopenharmony_ciprocessed by usr/gen_init_cpio.
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ciSee also 'usr/gen_initramfs.sh -h'.
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciWhere's this all leading?
8562306a36Sopenharmony_ci=========================
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ciThe klibc distribution contains some of the necessary software to make
8862306a36Sopenharmony_ciearly userspace useful.  The klibc distribution is currently
8962306a36Sopenharmony_cimaintained separately from the kernel.
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciYou can obtain somewhat infrequent snapshots of klibc from
9262306a36Sopenharmony_cihttps://www.kernel.org/pub/linux/libs/klibc/
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciFor active users, you are better off using the klibc git
9562306a36Sopenharmony_cirepository, at https://git.kernel.org/?p=libs/klibc/klibc.git
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciThe standalone klibc distribution currently provides three components,
9862306a36Sopenharmony_ciin addition to the klibc library:
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci- ipconfig, a program that configures network interfaces.  It can
10162306a36Sopenharmony_ci  configure them statically, or use DHCP to obtain information
10262306a36Sopenharmony_ci  dynamically (aka "IP autoconfiguration").
10362306a36Sopenharmony_ci- nfsmount, a program that can mount an NFS filesystem.
10462306a36Sopenharmony_ci- kinit, the "glue" that uses ipconfig and nfsmount to replace the old
10562306a36Sopenharmony_ci  support for IP autoconfig, mount a filesystem over NFS, and continue
10662306a36Sopenharmony_ci  system boot using that filesystem as root.
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cikinit is built as a single statically linked binary to save space.
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciEventually, several more chunks of kernel functionality will hopefully
11162306a36Sopenharmony_cimove to early userspace:
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci- Almost all of init/do_mounts* (the beginning of this is already in
11462306a36Sopenharmony_ci  place)
11562306a36Sopenharmony_ci- ACPI table parsing
11662306a36Sopenharmony_ci- Insert unwieldy subsystem that doesn't really need to be in kernel
11762306a36Sopenharmony_ci  space here
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciIf kinit doesn't meet your current needs and you've got bytes to burn,
12062306a36Sopenharmony_cithe klibc distribution includes a small Bourne-compatible shell (ash)
12162306a36Sopenharmony_ciand a number of other utilities, so you can replace kinit and build
12262306a36Sopenharmony_cicustom initramfs images that meet your needs exactly.
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciFor questions and help, you can sign up for the early userspace
12562306a36Sopenharmony_cimailing list at https://www.zytor.com/mailman/listinfo/klibc
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciHow does it work?
12862306a36Sopenharmony_ci=================
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ciThe kernel has currently 3 ways to mount the root filesystem:
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cia) all required device and filesystem drivers compiled into the kernel, no
13362306a36Sopenharmony_ci   initrd.  init/main.c:init() will call prepare_namespace() to mount the
13462306a36Sopenharmony_ci   final root filesystem, based on the root= option and optional init= to run
13562306a36Sopenharmony_ci   some other init binary than listed at the end of init/main.c:init().
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cib) some device and filesystem drivers built as modules and stored in an
13862306a36Sopenharmony_ci   initrd.  The initrd must contain a binary '/linuxrc' which is supposed to
13962306a36Sopenharmony_ci   load these driver modules.  It is also possible to mount the final root
14062306a36Sopenharmony_ci   filesystem via linuxrc and use the pivot_root syscall.  The initrd is
14162306a36Sopenharmony_ci   mounted and executed via prepare_namespace().
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cic) using initramfs.  The call to prepare_namespace() must be skipped.
14462306a36Sopenharmony_ci   This means that a binary must do all the work.  Said binary can be stored
14562306a36Sopenharmony_ci   into initramfs either via modifying usr/gen_init_cpio.c or via the new
14662306a36Sopenharmony_ci   initrd format, an cpio archive.  It must be called "/init".  This binary
14762306a36Sopenharmony_ci   is responsible to do all the things prepare_namespace() would do.
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci   To maintain backwards compatibility, the /init binary will only run if it
15062306a36Sopenharmony_ci   comes via an initramfs cpio archive.  If this is not the case,
15162306a36Sopenharmony_ci   init/main.c:init() will run prepare_namespace() to mount the final root
15262306a36Sopenharmony_ci   and exec one of the predefined init binaries.
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ciBryan O'Sullivan <bos@serpentine.com>
155