After linux starts the kernel, the root file system will be built, and then the init process can be used to start other applications
1. Why do I need a root file system
- The init process is in the root file system, so the root file system is needed to provide the init process to the kernel
- The root file system provides a root directory. linux can manage linux files through the root file system.
- The files in the etc directory are used to configure the linux kernel. These files are stored in the root file system.
- shell command program in root file system (busybox in root file system)
Only the kernel itself cannot work. The root file system (configuration file in / etc directory, shell command, library file in / lib directory) must be used to work
2. Steps to build the root file system
Building the root file system is divided into the following steps:
- Create a root directory, mount the rootfs file system (at this time, the system is in memory and there is no content in it), and parse the uboot parameter to know which path to mount to the real root file system later
- Unzip the initrd stored in the kernel, that is, initramfs (intermediate root file system)
- initramfs starts its own initrc script to mount the block device module
- Mount to the root file system on disk according to the root command
- Start the init process and start the terminal
2.1 create root directory and resolve uboot parameters
The process of creating the root directory is at start_kernel implemented
The reference for parsing uboot is also at start_kernel Implementation
start_kernel-> vfs_caches_init() mnt_init() init_rootfs(); //Initialize rootts init_mount_tree();//Mount rootts
Mainly init_rootfs() and init_mount_tree();
At this time, the root directory '' has been created, but it is empty and there is no specific file system, so the operating system can't get up yet
The next step is to mount the root file system
Let's think about a problem. If we want the instruction kernel to mount the block device of the instruction path, such as root=/dev/mtdblock3, how does the system identify it
2.2 parsing uboot parameters
reference resources: https://www.cnblogs.com/lifexy/p/7366792.html
If the specified root file system path is set, it will be displayed at start_ Parse the parameters passed from uboot in the kernel
asmlinkage void __init start_kernel(void) { ... setup_arch(&command_line); //Resolve the startup parameters passed in by uboot setup_command_line(command_line); //Resolve the startup parameters passed in by uboot .... /*Find kernel parameters*/ parse_early_param() { do_early_param(); //From__ setup_start to__ setup_end find the function with early non-0, which will be analyzed later } /*Find kernel parameters*/ unknown_bootoption() { obsolete_checksetup(); //From__ setup_start to__ setup_end find the function with early 0, which will be analyzed later } ... rest_init(); //Enter rest_init() }
After parsing, root=/dev/mtdblock3 in the bootags parameter will be saved in saved_root_name, then prepare_namespace (described later) will read this value and mount the root file system under this path
2.3 unzip the initrd stored in the kernel, i.e. initramfs (intermediate root file system)
Let's think about how to mount the root file system when there is no root file system at the beginning. If the root file system is placed on the disk, how to initialize the disk.
At this time, we need an initrd (initramfs) stored in ram to provide an intermediate root file system. The initrc script is provided in the intermediate root file system. With this script and the file system environment provided, we can do some initialization work, such as udev disk, mount to disk space, etc
kernel_init do_basic_setup rootfs_initcall(populate_rootfs)
populate_ The rootfs function decompresses the compiled initramfs file system to the root directory of rootfs and loads the initrd file.
populate_rootfs() calls unpack_to_rootfs() reads and parses the initrd file from memory;
And use sys_dir(),sys_open(),sys_mknod(),sys_symlink() and other system calls create new directories, regular files, special files and symbolic link files. At this time, VFS grows from the root directory "/" to a tree with rich content.
3. Mount to the root file system on the disk according to the root command
static int __init kernel_init(void * unused) //Enter init process { prepare_namespace() //Mount root file system { ... ... / /"Through parsed command line parameters" root=/dev/mtdblock3"To mount the root file system mount_root(); //Start mounting } init_post(); //application was launched }
prepare_namespace mount_root()//Mount the actual file system to the / root directory of rootfs
4. Start the init process and start the terminal
if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret) return 0; pr_err("Failed to execute %s (error %d)\n", ramdisk_execute_command, ret); } /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) { ret = run_init_process(execute_command); if (!ret) return 0; pr_err("Failed to execute %s (error %d). Attempting defaults...\n", execute_command, ret); } if (!try_to_run_init_process("/sbin/init") || !try_to_run_init_process("/etc/init") || !try_to_run_init_process("/bin/init") || !try_to_run_init_process("/bin/sh")) return 0; panic("No working init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance.");
Determine whether the root file system can access ramdisk_execute_command points to the init program. If possible, execute the init process
If the root file system is successfully mounted and / init is in it, the init process will be started
If execute is defined_ Command goes to the root directory to find the corresponding application, and then starts it
If ramdisk_execute_command and execute_ No application defined by command was found,
Go to the root directory to find / sbin/init, / etc/init, / bin/init,/bin/sh to start
5. What is needed to build the smallest root file system
Summarize what is needed for the smallest root file system
- Terminal / dev/console set / dev/null (if standard input is not set, output, error - > bottomless hole, output cannot be seen)
- Set the configuration culture inittab (application or default configuration specified in the configuration file)
- Need libraries (we think all fopen and fread in our own. c files are c libraries)
- init itself, busybox
Later, we will analyze the work of the init process