本文只是爲了演示Linux系統啓動過程所必要的元素,並非真正意義上的功能完備的Linux系統。
我的環境是VMware虛擬機,CentOS-6.7-x86_64操作系統。
首先爲虛擬機添加一塊磁盤,我這裏使用默認20G,其實不需要這麼大,不過虛擬機嘛,你不選立即分配,它也不會真的佔那麼大空間。
首先對它進行分區,使用MBR分區表。規劃三個分區,一個boot分區200M,一個swap分區2G,剩餘空間都給根分區。
[root@localhost ~]# parted -s /dev/sdb mklabel msdos [root@localhost ~]# parted -s /dev/sdb mkpart primary 2048s 200M [root@localhost ~]# parted -s /dev/sdb mkpart primary 200M 2200M [root@localhost ~]# parted -s /dev/sdb mkpart primary 2200M 100% [root@localhost ~]# partx -a /dev/sdb [root@localhost ~]# mkfs.ext4 /dev/sdb1 [root@localhost ~]# mkswap /dev/sdb2 [root@localhost ~]# mkfs.ext4 /dev/sdb3 [root@localhost ~]# parted -s /dev/sdb print Model: VMware, VMware Virtual S (scsi) Disk /dev/sdb: 21.5GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1049kB 200MB 199MB primary ext4 2 200MB 2200MB 2000MB primary linux-swap(v1) 3 2200MB 21.5GB 19.3GB primary ext4
在/mnt目錄下建立目錄作爲最簡化系統的根,將規劃作爲根分區/dev/sdb3的掛載至該目錄。
[root@localhost mnt]# mkdir sysroot [root@localhost mnt]# mount /dev/sdb3 /mnt/sysroot/
在/mnt/sysroot目錄下建立FHS目錄結構
[root@localhost ~]# cd /mnt/sysroot/ [root@localhost sysroot]# for d in $(ls /); do mkdir -v $d; done mkdir: created directory `bin' mkdir: created directory `boot' mkdir: created directory `dev' mkdir: created directory `etc' mkdir: created directory `home' mkdir: created directory `lib' mkdir: created directory `lib64' mkdir: cannot create directory `lost+found': File exists mkdir: created directory `media' mkdir: created directory `misc' mkdir: created directory `mnt' mkdir: created directory `net' mkdir: created directory `opt' mkdir: created directory `proc' mkdir: created directory `root' mkdir: created directory `sbin' mkdir: created directory `selinux' mkdir: created directory `srv' mkdir: created directory `sys' mkdir: created directory `tmp' mkdir: created directory `usr' mkdir: created directory `var'
將boot分區/dev/sdb1掛載至/mnt/sysroot/boot
[root@localhost sysroot]# mount /dev/sdb1 /mnt/sysroot/boot [root@localhost sysroot]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg0-root 20G 301M 19G 2% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 36M 145M 20% /boot /dev/mapper/vg0-usr 9.8G 2.0G 7.4G 21% /usr /dev/mapper/vg0-var 20G 136M 19G 1% /var /dev/sdb3 18G 45M 17G 1% /mnt/sysroot /dev/sdb1 180M 1.6M 169M 1% /mnt/sysroot/boot
在sdb上安裝grub,可以看到Grub將grub目錄安裝到了/mnt/sysroot/boot目錄下了。其實還有部分代碼是直接寫入了磁盤的物理扇區上,比如stage1是直接寫入了MBR的前446字節,而根據boot分區的文件類型不同,會將相應的stage1_5代碼也寫入磁盤的物理扇區靠前的位置,這裏應該寫的是e2fs_stage1_5。
[root@localhost sysroot]# grub-install --root-directory=/mnt/sysroot/ /dev/sdb Probing devices to guess BIOS drives. This may take a long time. Installation finished. No error reported. This is the contents of the device map /mnt/sysroot//boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (fd0)/dev/fd0 (hd0)/dev/sda (hd1)/dev/sdb [root@localhost ~]# ls /mnt/sysroot/boot/grub/ device.map ffs_stage1_5 minix_stage1_5 stage2 xfs_stage1_5 e2fs_stage1_5 iso9660_stage1_5 reiserfs_stage1_5 ufs2_stage1_5 fat_stage1_5 jfs_stage1_5 stage1 vstafs_stage1_5
直接使用CentOS-6的內核和僞根文件系統,不搞那麼複雜了,版本號都不要了。
[root@localhost boot]# cd /mnt/sysroot/boot [root@localhost boot]# cp /boot/vmlinuz-2.6.32-573.el6.x86_64 ./vmlinuz [root@localhost boot]# cp /boot/initramfs-2.6.32-573.el6.x86_64.img ./initramfs [root@localhost boot]# ls grub initramfs lost+found vmlinuz
內核啓動完成後,還需要啓動系統初始化程序,不過真的完成整個系統初始化過程,需要很多其他程序協作,太過複雜。其實也可以隨便指定一個別的程序,這裏我們爲了簡化,直接啓動一個bash,所以需要把bash移植過去。
[root@localhost ~]# which bash /bin/bash [root@localhost ~]# cp /bin/bash /mnt/sysroot/bin/
僅是這樣還不夠,bash是運行不起來的,它還依賴一些庫文件,因此這些庫文件也需要移植。
[root@localhost ~]# ldd /bin/bash linux-vdso.so.1 => (0x00007ffe8fbba000) libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003e81000000) libdl.so.2 => /lib64/libdl.so.2 (0x0000003e76c00000) libc.so.6 => /lib64/libc.so.6 (0x0000003e77000000) /lib64/ld-linux-x86-64.so.2 (0x0000003e76800000) [root@localhost ~]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/ [root@localhost ~]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64/ [root@localhost ~]# cp /lib64/libc.so.6 /mnt/sysroot/lib64/ [root@localhost ~]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/
現在還缺一個grub的配置文件,可以自己動手一個。因爲我們是準備把這塊硬盤拆下來,掛到另一個新建的虛擬機上,所以那個新建的虛擬機只有這一塊盤,(hd0,0)和/dev/sda3就是這麼來的。另外CentOS啓動時默認就會加載SELinux,而這個簡化的系統什麼都沒有,所以它會影響啓動,要把它關掉。
[root@localhost ~]# cat /mnt/sysroot/boot/grub/grub.conf default 0 timeout 5 title MiniLinux root (hd0,0) kernel /vmlinuz root=/dev/sda3 selinux=0 init=/bin/bash initrd /initramfs
所有這些做完之後,執行N遍sync命令,通知內核將改變立即寫入磁盤,然後關機或掛起。
新建一個虛擬機,使用在選擇磁盤處選擇使用剛剛修改的這塊磁盤,然後啓動。
可以看到grub正常啓動了。
bash也正常啓動起來了。
可以看到,除了bash的內建命令外,其他的命令都無法執行,所以說這只是一個演示系統啓動流程的最簡化的Linux系統,距離擁有完備功能的Linux系統還很遠。