18c2ecf20Sopenharmony_ci======================= 28c2ecf20Sopenharmony_ciEarly userspace support 38c2ecf20Sopenharmony_ci======================= 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciLast update: 2004-12-20 tlh 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci"Early userspace" is a set of libraries and programs that provide 98c2ecf20Sopenharmony_civarious pieces of functionality that are important enough to be 108c2ecf20Sopenharmony_ciavailable while a Linux kernel is coming up, but that don't need to be 118c2ecf20Sopenharmony_cirun inside the kernel itself. 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciIt consists of several major infrastructure components: 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci- gen_init_cpio, a program that builds a cpio-format archive 168c2ecf20Sopenharmony_ci containing a root filesystem image. This archive is compressed, and 178c2ecf20Sopenharmony_ci the compressed image is linked into the kernel image. 188c2ecf20Sopenharmony_ci- initramfs, a chunk of code that unpacks the compressed cpio image 198c2ecf20Sopenharmony_ci midway through the kernel boot process. 208c2ecf20Sopenharmony_ci- klibc, a userspace C library, currently packaged separately, that is 218c2ecf20Sopenharmony_ci optimized for correctness and small size. 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciThe cpio file format used by initramfs is the "newc" (aka "cpio -H newc") 248c2ecf20Sopenharmony_ciformat, and is documented in the file "buffer-format.txt". There are 258c2ecf20Sopenharmony_citwo ways to add an early userspace image: specify an existing cpio 268c2ecf20Sopenharmony_ciarchive to be used as the image or have the kernel build process build 278c2ecf20Sopenharmony_cithe image from specifications. 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ciCPIO ARCHIVE method 308c2ecf20Sopenharmony_ci------------------- 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciYou can create a cpio archive that contains the early userspace image. 338c2ecf20Sopenharmony_ciYour cpio archive should be specified in CONFIG_INITRAMFS_SOURCE and it 348c2ecf20Sopenharmony_ciwill be used directly. Only a single cpio file may be specified in 358c2ecf20Sopenharmony_ciCONFIG_INITRAMFS_SOURCE and directory and file names are not allowed in 368c2ecf20Sopenharmony_cicombination with a cpio archive. 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciIMAGE BUILDING method 398c2ecf20Sopenharmony_ci--------------------- 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciThe kernel build process can also build an early userspace image from 428c2ecf20Sopenharmony_cisource parts rather than supplying a cpio archive. This method provides 438c2ecf20Sopenharmony_cia way to create images with root-owned files even though the image was 448c2ecf20Sopenharmony_cibuilt by an unprivileged user. 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciThe image is specified as one or more sources in 478c2ecf20Sopenharmony_ciCONFIG_INITRAMFS_SOURCE. Sources can be either directories or files - 488c2ecf20Sopenharmony_cicpio archives are *not* allowed when building from sources. 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciA source directory will have it and all of its contents packaged. The 518c2ecf20Sopenharmony_cispecified directory name will be mapped to '/'. When packaging a 528c2ecf20Sopenharmony_cidirectory, limited user and group ID translation can be performed. 538c2ecf20Sopenharmony_ciINITRAMFS_ROOT_UID can be set to a user ID that needs to be mapped to 548c2ecf20Sopenharmony_ciuser root (0). INITRAMFS_ROOT_GID can be set to a group ID that needs 558c2ecf20Sopenharmony_cito be mapped to group root (0). 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciA source file must be directives in the format required by the 588c2ecf20Sopenharmony_ciusr/gen_init_cpio utility (run 'usr/gen_init_cpio -h' to get the 598c2ecf20Sopenharmony_cifile format). The directives in the file will be passed directly to 608c2ecf20Sopenharmony_ciusr/gen_init_cpio. 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciWhen a combination of directories and files are specified then the 638c2ecf20Sopenharmony_ciinitramfs image will be an aggregate of all of them. In this way a user 648c2ecf20Sopenharmony_cican create a 'root-image' directory and install all files into it. 658c2ecf20Sopenharmony_ciBecause device-special files cannot be created by a unprivileged user, 668c2ecf20Sopenharmony_cispecial files can be listed in a 'root-files' file. Both 'root-image' 678c2ecf20Sopenharmony_ciand 'root-files' can be listed in CONFIG_INITRAMFS_SOURCE and a complete 688c2ecf20Sopenharmony_ciearly userspace image can be built by an unprivileged user. 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciAs a technical note, when directories and files are specified, the 718c2ecf20Sopenharmony_cientire CONFIG_INITRAMFS_SOURCE is passed to 728c2ecf20Sopenharmony_ciusr/gen_initramfs.sh. This means that CONFIG_INITRAMFS_SOURCE 738c2ecf20Sopenharmony_cican really be interpreted as any legal argument to 748c2ecf20Sopenharmony_cigen_initramfs.sh. If a directory is specified as an argument then 758c2ecf20Sopenharmony_cithe contents are scanned, uid/gid translation is performed, and 768c2ecf20Sopenharmony_ciusr/gen_init_cpio file directives are output. If a directory is 778c2ecf20Sopenharmony_cispecified as an argument to usr/gen_initramfs.sh then the 788c2ecf20Sopenharmony_cicontents of the file are simply copied to the output. All of the output 798c2ecf20Sopenharmony_cidirectives from directory scanning and file contents copying are 808c2ecf20Sopenharmony_ciprocessed by usr/gen_init_cpio. 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciSee also 'usr/gen_initramfs.sh -h'. 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ciWhere's this all leading? 858c2ecf20Sopenharmony_ci========================= 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ciThe klibc distribution contains some of the necessary software to make 888c2ecf20Sopenharmony_ciearly userspace useful. The klibc distribution is currently 898c2ecf20Sopenharmony_cimaintained separately from the kernel. 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciYou can obtain somewhat infrequent snapshots of klibc from 928c2ecf20Sopenharmony_cihttps://www.kernel.org/pub/linux/libs/klibc/ 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ciFor active users, you are better off using the klibc git 958c2ecf20Sopenharmony_cirepository, at https://git.kernel.org/?p=libs/klibc/klibc.git 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciThe standalone klibc distribution currently provides three components, 988c2ecf20Sopenharmony_ciin addition to the klibc library: 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci- ipconfig, a program that configures network interfaces. It can 1018c2ecf20Sopenharmony_ci configure them statically, or use DHCP to obtain information 1028c2ecf20Sopenharmony_ci dynamically (aka "IP autoconfiguration"). 1038c2ecf20Sopenharmony_ci- nfsmount, a program that can mount an NFS filesystem. 1048c2ecf20Sopenharmony_ci- kinit, the "glue" that uses ipconfig and nfsmount to replace the old 1058c2ecf20Sopenharmony_ci support for IP autoconfig, mount a filesystem over NFS, and continue 1068c2ecf20Sopenharmony_ci system boot using that filesystem as root. 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cikinit is built as a single statically linked binary to save space. 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ciEventually, several more chunks of kernel functionality will hopefully 1118c2ecf20Sopenharmony_cimove to early userspace: 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci- Almost all of init/do_mounts* (the beginning of this is already in 1148c2ecf20Sopenharmony_ci place) 1158c2ecf20Sopenharmony_ci- ACPI table parsing 1168c2ecf20Sopenharmony_ci- Insert unwieldy subsystem that doesn't really need to be in kernel 1178c2ecf20Sopenharmony_ci space here 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ciIf kinit doesn't meet your current needs and you've got bytes to burn, 1208c2ecf20Sopenharmony_cithe klibc distribution includes a small Bourne-compatible shell (ash) 1218c2ecf20Sopenharmony_ciand a number of other utilities, so you can replace kinit and build 1228c2ecf20Sopenharmony_cicustom initramfs images that meet your needs exactly. 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ciFor questions and help, you can sign up for the early userspace 1258c2ecf20Sopenharmony_cimailing list at https://www.zytor.com/mailman/listinfo/klibc 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ciHow does it work? 1288c2ecf20Sopenharmony_ci================= 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ciThe kernel has currently 3 ways to mount the root filesystem: 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cia) all required device and filesystem drivers compiled into the kernel, no 1338c2ecf20Sopenharmony_ci initrd. init/main.c:init() will call prepare_namespace() to mount the 1348c2ecf20Sopenharmony_ci final root filesystem, based on the root= option and optional init= to run 1358c2ecf20Sopenharmony_ci some other init binary than listed at the end of init/main.c:init(). 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cib) some device and filesystem drivers built as modules and stored in an 1388c2ecf20Sopenharmony_ci initrd. The initrd must contain a binary '/linuxrc' which is supposed to 1398c2ecf20Sopenharmony_ci load these driver modules. It is also possible to mount the final root 1408c2ecf20Sopenharmony_ci filesystem via linuxrc and use the pivot_root syscall. The initrd is 1418c2ecf20Sopenharmony_ci mounted and executed via prepare_namespace(). 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cic) using initramfs. The call to prepare_namespace() must be skipped. 1448c2ecf20Sopenharmony_ci This means that a binary must do all the work. Said binary can be stored 1458c2ecf20Sopenharmony_ci into initramfs either via modifying usr/gen_init_cpio.c or via the new 1468c2ecf20Sopenharmony_ci initrd format, an cpio archive. It must be called "/init". This binary 1478c2ecf20Sopenharmony_ci is responsible to do all the things prepare_namespace() would do. 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci To maintain backwards compatibility, the /init binary will only run if it 1508c2ecf20Sopenharmony_ci comes via an initramfs cpio archive. If this is not the case, 1518c2ecf20Sopenharmony_ci init/main.c:init() will run prepare_namespace() to mount the final root 1528c2ecf20Sopenharmony_ci and exec one of the predefined init binaries. 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ciBryan O'Sullivan <bos@serpentine.com> 155