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