Using linux kernel +busybox to customize linux system

Keywords: Linux CentOS vim yum

Objective:

Understanding the linux startup process

Main contents:

Grub is the bootloader of the boot program
2. linux kernel is the open source kernel of linux
3.busybox is a collection of linux tools

Start sequence:

Grub - > bzimage > initrd > init > chroot SBIN / init > / etc / inittab > fstab > etc / init.d/rcs

Experimental environment:

Operating system (compiled): CentOS 7.4 kernel version: 5.5.2
1. Compile linux kernel
1) Download and unzip:

https://www.kernel.org/
//Current version 5.5.2
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.5.2.tar.xz
//Copy files to / usr/src/linux-5.5.2.tar.xz
//Unzip tar-xvf linux-5.5.2.tar.xz

2) Compile linux kernel:
1 yum install ncusres‐devel # Some packages compiled as needed
2 cd /usr/src/linux‐5.5.2 # Switch to linux source directory
3 make menuconfig #Configure the kernel compilation content and some information. Because it is a demonstration, it is OK by default
4 make ‐j4 #Perform multi cpu compilation
5 midir /usr/src/modules
6 make modules_install INSTALL_MOD_PATH=/usr/src/modules #Install modules here

2. Compile busybox
1) Download and unzip:
https://busybox.net/
Current version 1.31.1
https://busybox.net/downloads/busybox-1.31.1.tar.bz2
Copy the file to / usr/src/busybox-1.31.1.tar.bz2
Unzip tar-jxvf busybox-1.31.1.tar.bz2

2) Compiling busybox
1 yum install glibc‐static # Static library packages compiled as needed
2 cd /usr/src/busybox‐1.31.1 # Switch to busybox source directory
3 make menuconfig # Configure Settings - > build options - > build static binary
4 make install

3. Create initrd.gz file according to busybox
1 make /usr/src/initrd # Create initialization directory
2 cd /usr/src/initrd # Enter working directory
3 cp /usr/src/busybox‐1.31.1/_install/* ‐a . #Copy all busybox files
4 mkdir proc sys mnt/sysroot dev tmp etc ‐pv #Create necessary directories
5 mknod dev/console c 5 1 # Create console device
6 mknod dev/null c 1 3 # Create null device
7 rm linuxrc # Delete the soft connection. This file is useless and uncomfortable
8 touch init # Create init bootstrap. See the following information for details
9 chmod +x init # Set up the runnable program
10 find . | cpio ‐H newc ‐‐quiet ‐o | gzip ‐9 > /usr/src/initrd.gz #Pack initrd

init file content:
1 #!/bin/sh
2
3 echo "Mounting proc and sys..."
4 mount ‐t sysfs sysfs /sys
5 mount ‐t proc proc /proc
6
7 echo "Detect and export hardware infomation..."
8 mdev ‐s
9
10 echo "Mount real rootfs to /mnt/sysroot..."
11 mount ‐t ext4 ‐o ro /dev/sda2 /mnt/sysroot
12
13 echo "Switch to real rootfs..."
14 exec chroot /mnt/sysroot /sbin/init

4. Compile the output into vmlinuz according to linux kernel
1 cp /usr/src/linux‐5.5.2/arch/x86/boot/bzImage /usr/src/vmlinuz #Duplicate kernel

5. Make the real linux directory of rootfs system according to busybox
1 make /usr/src/sysroot #Create working directory
2 cd sysroot #Enter working directory
3 cp /usr/src/busybox‐1.31.1/_install/* ‐a . #Copy all busybox files
4 rm linuxrc # Delete the soft connection. This file is useless and uncomfortable
5 # Create directory
6 mkdir dev var sys mnt etc proc lib home tmp root boot
7 mkdir var/{log,run,lock}
8 mkdir lib/modules
9 mknod dev/console c 5 1 # Create console device
10 mknod dev/null c 1 3 # Create null device
11 vim etc/inittab #Create the rootfs startup file, as shown in the following figure
12 vim etc/init.d/rcS #Create startup script
13 chmod +x rcS
14 vim etc/fstab #When mount ‐ a is executed, the mount in this file will be executed

inittab file content:
1 ::sysinit:/etc/init.d/rcS
2 ::askfirst:‐/bin/sh
3 ::ctrlaltdel:/sbin/reboot
4 ::shutdown:/bin/umount ‐a ‐r
5 ::restart:/sbin/init

rcS file content:
1 #!/bin/sh
2
3 echo ‐e "Welcome To My Linux"
4
5 echo "Remount the rootfs..."
6 mount ‐t ext4 ‐o remount,rw /dev/sda2 /
7 echo "Detect and export hardware infomation..."
8 mdev ‐s
9 echo "Mount the other filesystem...fstab"
10 mount ‐a

fstab:
1 # device mount‐point type options dump fsck
2 sysfs /sys sysfs defaults 0 0
3 proc /proc proc defaults 0 0
4 /dev/sda1 /boot ext4 defaults 0 0
5 /dev/sda2 / ext4 defaults 1 1

6. After the above steps, vmlinuz(linux kernel) initrd.gz (memory system disk) and sysroot (real linux rootfs system) have been implemented. Next, a disk has been prepared.
Create a sata disk 10G through virtual box and divide it into two sections
1 [root@centos ~]# lsblk
2 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
3 sda 8:0 0 100G 0 disk
4 ├─sda1 8:1 0 1G 0 part /boot
5 └─sda2 8:2 0 99G 0 part
6 ├─cl‐root 253:0 0 50G 0 lvm /
7 ├─cl‐swap 253:1 0 2G 0 lvm [SWAP]
8 └─cl‐home 253:2 0 47G 0 lvm /home
9 sdb 8:16 0 10G 0 disk
10 sr0 11:0 1 1024M 0 rom
11 ###############################################
12 [root@centos ~]# fdisk /dev/sdb #Start formatting
13 Welcome to fdisk (util‐linux 2.23.2).
14
15 Changes will remain in memory only, until you decide to write them.
16 Be careful before using the write command.
17
18 Device does not contain a recognized partition table
19 Building a new DOS disklabel with disk identifier 0x3f5d5436.
20
21 Command (m for help): n
22 Partition type:
23 p primary (0 primary, 0 extended, 4 free)
24 e extended
25 Select (default p): p
26 Partition number (1‐4, default 1): 1
27 First sector (2048‐20971519, default 2048): 2048
28 Last sector, +sectors or +size{K,M,G} (2048‐20971519, default 20971519):
+5G
29 Partition 1 of type Linux and of size 5 GiB is set
30
31 Command (m for help): n
32 Partition type:
33 p primary (1 primary, 0 extended, 3 free)
34 e extended
35 Select (default p): p
36 Partition number (2‐4, default 2):
37 First sector (10487808‐20971519, default 10487808):
38 Using default value 10487808
39 Last sector, +sectors or +size{K,M,G} (10487808‐20971519, default 209715
19):
40 Using default value 20971519
41 Partition 2 of type Linux and of size 5 GiB is set
42
43 Command (m for help): p
44
45 Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
46 Units = sectors of 1 * 512 = 512 bytes
47 Sector size (logical/physical): 512 bytes / 512 bytes
48 I/O size (minimum/optimal): 512 bytes / 512 bytes
49 Disk label type: dos
50 Disk identifier: 0x3f5d5436
51
52 Device Boot Start End Blocks Id System
53 /dev/sdb1 2048 10487807 5242880 83 Linux
54 /dev/sdb2 10487808 20971519 5241856 83 Linux
55
56 Command (m for help): w
57 The partition table has been altered!
58
59 Calling ioctl() to re‐read partition table.
60 Syncing disks.
61 [root@centos ~]#

Start to mount the partitioned disks and copy the files to these two partitions. The first partition is defined as boot and the second partition as sysroot;
1 mkdir /mnt/boot /mnt/sysroot # Create two directories on centos system
2 [root@centos src]# lsblk # View the sdb disk just divided
3 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
4 sda 8:0 0 100G 0 disk
5 ├─sda1 8:1 0 1G 0 part /boot
6 └─sda2 8:2 0 99G 0 part
7 ├─cl‐root 253:0 0 50G 0 lvm /
8 ├─cl‐swap 253:1 0 2G 0 lvm [SWAP]
9 └─cl‐home 253:2 0 47G 0 lvm /home
10 sdb 8:16 0 10G 0 disk
11 ├─sdb1 8:17 0 5G 0 part
12 └─sdb2 8:18 0 5G 0 part
13 sr0 11:0 1 1024M 0 rom
14
15 [root@centos mnt]# mkfs.ext4 /dev/sdb1 #Create file system format
16 mke2fs 1.42.9 (28‐Dec‐2013)
17 Filesystem label=
18 OS type: Linux
19 Block size=4096 (log=2)
20 Fragment size=4096 (log=2)
21 Stride=0 blocks, Stripe width=0 blocks
22 327680 inodes, 1310720 blocks
23 65536 blocks (5.00%) reserved for the super user
24 First data block=0
25 Maximum filesystem blocks=1342177280
26 40 block groups
27 32768 blocks per group, 32768 fragments per group
28 8192 inodes per group
29 Superblock backups stored on blocks:
30 32768, 98304, 163840, 229376, 294912, 819200, 884736
31
32 Allocating group tables: done
33 Writing inode tables: done
34 Creating journal (32768 blocks): done
35 Writing superblocks and filesystem accounting information: done
36
37 [root@centos mnt]# mkfs.ext4 /dev/sdb2
38 mke2fs 1.42.9 (28‐Dec‐2013)
39 Filesystem label=
40 OS type: Linux
41 Block size=4096 (log=2)
42 Fragment size=4096 (log=2)
43 Stride=0 blocks, Stripe width=0 blocks
44 327680 inodes, 1310464 blocks
45 65523 blocks (5.00%) reserved for the super user
46 First data block=0
47 Maximum filesystem blocks=1342177280
48 40 block groups
49 32768 blocks per group, 32768 fragments per group
50 8192 inodes per group
51 Superblock backups stored on blocks:
52 32768, 98304, 163840, 229376, 294912, 819200, 884736
53
54 Allocating group tables: done
55 Writing inode tables: done
56 Creating journal (32768 blocks): done
57 Writing superblocks and filesystem accounting information: done
58
59 [root@centos mnt]# blkid
60 /dev/sda1: UUID="cbf299b0‐d76d‐4efe‐8643‐c900502683d4" TYPE="xfs"
61 /dev/sda2: UUID="L416ib‐7Z3D‐rtXt‐FqTb‐ChsW‐j6zH‐heeuF2" TYPE="LVM2_memb
er"
62 /dev/mapper/cl‐root: UUID="12c02980‐3012‐4884‐8a7d‐437195398fdb" TYPE="x
fs"
63 /dev/mapper/cl‐swap: UUID="c4ea26e2‐7424‐4a52‐aa34‐8d9fb4f3fbd2" TYPE="s
wap"
64 /dev/mapper/cl‐home: UUID="7be941f2‐fcf6‐44b7‐b673‐f999f1c876b0" TYPE="x
fs"
65 /dev/sdb1: UUID="78df7716‐e32f‐421e‐a756‐8fe89407e9ec" TYPE="ext4"
66 /dev/sdb2: UUID="c905f4d2‐ae58‐41f8‐85e6‐69d1f0237ad2" TYPE="ext4"
67 [root@centos mnt]#
68 [root@centos mnt]# mount /dev/sdb1 /mnt/boot
69 [root@centos mnt]# mount /dev/sdb2 /mnt/sysroot
70 [root@centos mnt]# df ‐h
71 Filesystem Size Used Avail Use% Mounted on
72 /dev/mapper/cl‐root 50G 27G 24G 53% /
73 devtmpfs 910M 0 910M 0% /dev
74 tmpfs 920M 0 920M 0% /dev/shm
75 tmpfs 920M 8.5M 912M 1% /run
76 tmpfs 920M 0 920M 0% /sys/fs/cgroup
77 /dev/sda1 1014M 185M 830M 19% /boot
78 /dev/mapper/cl‐home 47G 33M 47G 1% /home
79 tmpfs 184M 0 184M 0% /run/user/0
80 /dev/sdb1 4.8G 20M 4.6G 1% /mnt/boot
81 /dev/sdb2 4.8G 20M 4.6G 1% /mnt/sysroot

Start copying files compiled before
1 cp /usr/src/vmlinuz /mnt/boot/ #linux kernel
2 cp /usr/src/initrd.gz /mnt/boot/ #RAM disk memory image (from busybox transformation)
3 cp ‐a /usr/src/sysroot/* /mnt/sysroot/ #System catalog collection (from busybox transformation)
4 [root@centos /]# tree mnt ‐L 2
5 mnt
6 ├── boot
7 │ ├── initrd.gz
8 │ └── vmlinuz
9 └── sysroot
10 ├── bin
11 ├── boot
12 ├── dev
13 ├── etc
14 ├── home
15 ├── lib
16 ├── mnt
17 ├── proc
18 ├── root
19 ├── sbin
20 ├── sys
21 ├── tmp
22 ├── usr
23 └── var

7. Install grub boot program into sdb1
1. Yum install grub2 ‐ install. Because grub2 is adopted after centos7, it is installed directly
2 [root @ CentOS MNT] ා Grub2 ‐ install ‐ boot ‐ directory=/mnt/boot /dev/sdb ‐ install
Go to the boot directory
3 Installing for i386‐pc platform.
4 Installation finished. No error reported.
5 [root@centos boot]# ll
6 total 9248
7 drwxr‐xr‐x. 5 root root 4096 Feb 6 08:25 grub2
8 ‐rw‐r‐‐r‐‐. 1 root root 1484989 Feb 6 08:03 initrd.gz
9 ‐rw‐r‐‐r‐‐. 1 root root 7975904 Feb 6 08:04 vmlinuz
10 [root @ CentOS boot] ා Grub2 ‐ mkconfig ‐ o /mnt/boot/grub2/grub.cfg 񖓿 for my convenience, I used to generate automatically according to the system first, and then edit this file
11 [root @ CentOS boot] ා VIM / MNT / boot / Grub2 / grub.cfg ා see the figure below for editing contents, and remove many useless contents

grub.cfg file content, only keep a few core information
1 # relay display
2 set timeout=5
3 # entry
4 menuentry 'My Linux' {
5 insmod gzio
6 insmod part_msdos
7 insmod xfs
8 set root='hd0,msdos1'
9 linux16 /vmlinuz root=/dev/sda2
10 initrd16 /initrd.gz
11 }

8. Load the virtual hard disk just created through virtual, and start the virtual machine... At the beginning of witnessing miracles.
The welcome interface appears and the system is booted successfully.

Something went wrong...

Estimated guess analysis:
When the system starts, it needs to mount the real rootfs system, / dev/sda2. However, after loading the memory image initrd.gz, when you want to mount rootfs, you cannot find the hard disk partition.
Here's a package that we didn't package into the kernel when it came to third-party modules such as ext4 driver, but it supports extension mounting by default, so we modified initrd.gz At this time, modules are needed for this file (just generated before, but not yet used, so you need to package the modules into initrd.gz so that he can find the ext4 driver). At the same time, the rootfs directory is also processed as a mirror image.
sysroot and initrd operate in the same way:
1 cd /mnt/sysroot
2 cp ‐a /usr/src/modules/lib usr/ #Copy modules to enter this folder
3 mkdir usr/lib64 #Create an empty folder just to standardize it
4 ln ‐s usr/lib64 lib64
5 ln ‐s usr/lib lib
6 #initrd also operates
7 cd /usr/src/initrd
8 cp ‐a /usr/src/modules/lib usr/ #Copy modules to enter this folder
9 mkdir usr/lib64 #Create an empty folder just to standardize it
10 ln ‐s usr/lib64 lib64
11 ln ‐s usr/lib lib
12 # It takes a long time to regenerate initrd.gz because I haven't simplified the module
13 find . | cpio ‐H newc ‐‐quiet ‐o | gzip ‐9 > /usr/src/initrd.gz
14 # Replace the old initrd.gz
15 cp initrd.gz /mnt/boot/

By modifying the init file, although I went into the image system, I still couldn't find the hard disk, which led to rootfs not being able to enter. Please help me to untie this knot. I don't know where there is a problem.
Start to modify init without rootfs conversion, and enter the memory system directly:
1 #!/bin/sh
2
3 echo "Mounting proc and sys..."
4 mount ‐t sysfs sysfs /sys
5 mount ‐t proc proc /proc
6
7 echo "Detect and export hardware infomation..."
8 mdev ‐s
9
10 exec /bin/sh
11 Note out the two sentences of the project and change it to direct implementation exec /bin/sh As main process
12
13 echo "Mount real rootfs to /mnt/sysroot..."
14 #mount ‐t ext4 ‐o ro /dev/sda2 /mnt/sysroot
15
16 echo "Switch to real rootfs..."
17 # exec chroot /mnt/sysroot /sbin/init

At this time, the memory system is in:


But there is no hard disk partition of sdaX at all but under / dev /. First of all, there are drivers, which can be seen through grub.
cat /proc/filesystems


Enter the grub interface just started, and you can see the hard disk partition:


---The problem that the hard disk cannot be found has been solved. Add:
The problem that the hard disk cannot be found has been solved by modifying the linux kernel configuration:
Device Drivers > SCSI device Support >SCSI Disk Support
SCSI generic support


After modifying the kernel configuration, we finally found the hard disk:

Posted by dschreck on Sun, 09 Feb 2020 20:05:55 -0800