首頁 > 軟體

客製化屬於自己的Linux作業系統

2020-06-16 17:30:12

本文主要通過裁剪現有Linux系統,打造一個屬於自己的Linux小系統,讓其能夠裝載網絡卡驅動,並設定IP地址,實現網路功能。

自製Linux系統

步驟概述:

1、新建一個硬碟
2、在該新硬碟上新建兩個分割區,一個當boot分割區,一個當/分割區
3、格式化並且掛載兩個分割區
4、安裝grub至目標磁碟
5、為grub提供組態檔
6、複製核心檔案和initrd檔案
7、建立目標主機根檔案系統
8、移植bash命令和其庫檔案到根檔案系統
9、裝載模組,實現網路功能
10、啟動測試

特別提醒
如果在vmvare上做此實驗,在新建虛擬機器建立新磁碟的時候,一定要選“Store virtual disk as a single file”,否則,也會出現核心恐慌kennel panic。

步驟演示詳解過程:

1、新建一個硬碟

2、在該新硬碟上新建兩個分割區,一個當boot分割區,一個當/分割區
首先,我們要在目標磁碟上分兩個區,並進行格式化。第一個分割區100M,用來裝載入程式;第二個分割區19G,用來裝根檔案系統。然後再進行掛載操作,將/dev/sdb1掛載到/mnt/boot下,將/dev/sdb2掛載到/mnt/root下。

sdb                  8:16  0    20G  0 disk
├─sdb1                8:17  0 109.8M  0 part
└─sdb2                8:18  0  19.9G  0 part
[root@localhost ~]# fdisk -l /dev/sdb

Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xdd8058c2

  Device Boot      Start        End      Blocks  Id  System
/dev/sdb1              1          14      112423+  83  Linux
/dev/sdb2              15        2610    20852370  83  Linux

3、格式化並且掛載兩個分割區
注意,其中boot分割區的掛載目錄一定是boot名字的目錄

[root@localhost ~]# mkfs.ext4 /dev/sdb1
[root@localhost ~]# mkfs.ext4 /dev/sdb2
[root@localhost ~]# mkdir -p /mnt/{root,boot}
[root@localhost ~]# ll /mnt/
total 8
drwxr-xr-x 2 root root 4096 Jul 25 08:52 boot
drwxr-xr-x 2 root root 4096 Jul 25 08:52 root
[root@localhost ~]# mount /dev/sdb1 /mnt/boot/
[root@localhost ~]# mount /dev/sdb2 /mnt/root/
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1            103M  1.6M  96M  2% /mnt/boot
/dev/sdb2              20G  44M  19G  1% /mnt/root

4、安裝grub至目標磁碟
一個系統能啟動,就需要引導,所以我們首先要安裝一個grub載入程式到我們的新磁碟上,安裝grub載入程式主要有兩個命令,一個是grub-install,另一個是setup,這裡最好使用grub-install來安裝。因為:

①grub-install會安裝grub引導第二階段的檔案
②setup不會安裝第二階段的載入程式,是安裝引導資訊到MBR
//第二個需要注意的地方就是--root-directory=後面接的路徑應該是boot目錄所在的地方,而不是/mnt/boot,因為boot目錄在mnt下;目標磁碟是/dev/sdb
[root@localhost ~]# grub-install --root-directory=/mnt /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/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 ~]# cd /mnt/boot/
[root@localhost boot]# ll
total 13
drwxr-xr-x 2 root root  1024 Jul 25 08:58 grub
drwx------ 2 root root 12288 Jul 25 08:51 lost+found
安裝完grub後,進入grub目錄,會發現沒有grub.conf組態檔,這樣就導致我們的載入程式是不健全的,所以我們需要手動寫一個組態檔在裡邊。

5、為grub提供組態檔
上面移植了核心和initrd檔案,我們就可以根據核心版本和initrd版本來編寫grub.conf組態檔了:

default=0
timeout=5
title CentOS to ZhangHe Soft-Linux
root (hd0,0)
kernel /vmlinz-soft ro root=/dev/sda2 quiet selinux=0 init=/bin/bash
initrd /initramfs-soft.img
quiet是靜默安裝,不再顯示安裝時的一大堆資訊。後面要把selinux關掉,而且init要使用/bin/bash,告訴核心不要再去找init程式了。如果不指定這一步,在啟動過程中就會報kernel panic(核心恐慌),以為系統就它一個了,沒有init進程,恐慌的不行。

6、複製核心檔案和initrd檔案
init是系統中用來產生其它所有進程的程式。它以守護行程的方式存在,其進程號為1,init是所有進程的父進程,老祖宗,所以不移植是不行的。它通過呼叫/etc/inittab這個組態檔,然後再去執行/etc/rc.d/rc.sysinit的系統初始化指令碼。
將核心檔案和initrd檔案複製到/dev/sdb下的boot目錄中。

[root@localhost grub]# cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/vmlinuz-soft
[root@localhost grub]# cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot/initramfs-soft.img

7、建立目標主機根檔案系統
使用命令列展開建立檔案系統

[root@localhost grub]# mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,srv,mnt,media,home,root}
mkdir: created directory `/mnt/sysroot'
mkdir: created directory `/mnt/sysroot/etc'
mkdir: created directory `/mnt/sysroot/etc/rc.d'
mkdir: created directory `/mnt/sysroot/usr'
mkdir: created directory `/mnt/sysroot/var'
mkdir: created directory `/mnt/sysroot/proc'
mkdir: created directory `/mnt/sysroot/sys'
mkdir: created directory `/mnt/sysroot/dev'
mkdir: created directory `/mnt/sysroot/lib'
mkdir: created directory `/mnt/sysroot/lib64'
mkdir: created directory `/mnt/sysroot/bin'
mkdir: created directory `/mnt/sysroot/sbin'
mkdir: created directory `/mnt/sysroot/boot'
mkdir: created directory `/mnt/sysroot/srv'
mkdir: created directory `/mnt/sysroot/mnt'
mkdir: created directory `/mnt/sysroot/media'
mkdir: created directory `/mnt/sysroot/home'
mkdir: created directory `/mnt/sysroot/root'
[root@localhost mnt]# ls root/
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  proc  root  sbin  srv  sys  usr  var

8、移植bash命令和其庫檔案到根檔案系統
[root@localhost scripts]# bash cporder.sh
Enter a command: bash
Enter a command: shutdown
Enter a command: vim
Enter a command: reboot
Enter a command: touch
Enter a command: mkdir
Enter a command: ls
Enter a command: rm
Enter a command: cat
Enter a command: less
Enter a command: tree
Enter a command: ifconfig
Enter a command: ip
Enter a command: route
Enter a command: ping
Enter a command: quit
quit

附:命令移植指令碼

#!/bin/bash 

target=/mnt/root 
clearCmd() { 
if which $cmd &> /dev/null; then 
cmdPath=`which --skip-alias $cmd` 
else 
echo "No such command" 
return 5 
fi 

cmdCopy() { 
cmdDir=`dirname $1` 
[ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir} 
[ -f ${target}${1} ] || cp $1 ${target}${cmdDir} 

libCopy() { 
for lib in `ldd $1 | grep -o "/[^[:space:]]{1,}"`; do 
libDir=`dirname $lib` 
[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir} 
[ -f ${target}${lib} ] || cp $lib ${target}${libDir} 
done 

while true; do 
read -p "Enter a command: " cmd 
if [ "$cmd" == 'quit' ] ;then 
echo "quit" 
exit 0 
fi 
clearCmd $cmd 
[ $? -eq 5 ] && continue 
cmdCopy $cmdPath 
libCopy $cmdPath 
done 

9、裝載模組,實現網路功能
Linux是一個模組化的作業系統,好多功能元件都是通過模組化的工具來實現的,而且支援動態裝載和解除安裝,我們要是想實現某種功能,只需載入相應的模組即可,就可以實現我們的Linux作業系統大瘦身了。

1、檢視宿主機的網絡卡模組資訊

[root@localhost ~]# lsmod | grep e1000
e1000                134863  0

2、檢視網絡卡的詳細資訊

[root@localhost ~]# modinfo e1000
filename:      /lib/modules/2.6.32-642.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
version:        7.3.21-k8-NAPI
license:        GPL
description:    Intel(R) PRO/1000 Network Driver
author:        Intel Corporation, <linux.nics@intel.com>
srcversion:    A911791C4EFC2A93BCFCF6A
alias:          pci:v00008086d00002E6Esv*sd*bc*sc*i*
alias:          pci:v00008086d000010B5sv*sd*bc*sc*i*
alias:          pci:v00008086d00001099sv*sd*bc*sc*i*
alias:          pci:v00008086d0000108Asv*sd*bc*sc*i*
//這裡查詢到了網絡卡模組的路徑,把它複製到/dev/sdb的庫檔案下:
[root@localhost ~]# mkdir /mnt/root/lib64/modules
[root@localhost ~]# cp /lib/modules/2.6.32-642.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/root/lib64/modules/e1000.ko

3、init程式
現在雖然是模組複製過去了,但是還不能用,而且現在也不滿足我們的流程需要,因為連最起碼的init程式都沒有,如果我們想要這個init,有兩個選擇,第一,移植宿主系統的,但是格式會複雜一些;所以我們還是先自己動手寫指令碼吧,把指令碼當作init來用,能夠讓小系統跑起來。init一般在sbin目錄下,所以我們要在/dev/sdb2這個分割區上編寫一個init指令碼。

[root@localhost ~]# cd /mnt/root/sbin
[root@localhost sbin]# cd /mnt/root/sbin/
#!/bin/bash
#print Welcome info
echo -e "Welcome to 33[34m nmshuishui soft-Linux33[0m"
#mount wei wenjian system when the system is running.
mount -n -t proc proc /proc
mount -n -t sysfs sysfs /sys
#mount ethernet driver autl when the system is start.
insmod /lib64/modules/e1000.ko
[ $? -eq 0 ] && echo -e "Load e1000 module succeeded                    [33[32m0K33[0m]"
ifconfig lo 172.0.0.1/8
ifconfig eth0 172.16.251.235/16
#mount the /dev/sda2 to make it can be write and read.
mount -n -o remount,rw /dev/sda2 /
#run /bin/bash
/bin/bash

寫完這個init指令碼後,我們要把我們要給其一個執行許可權,讓其能夠被執行;此指令碼中還用到mount,insmod這些命令,所以要用上一個指令碼把這些命令移植過去。最後還需要把/mnt/boot/grub/grub.conf中的init=/bin/bash換成init=/sbin/init,因為我現在要用這個init指令碼來執行系統啟動了,再也不需讓/bin/bash來替換了。

10、啟動測試
上面的步驟完成後,就可以把/dev/sdb掛到另一台主機上體驗我們的私人訂製小系統了。

 

到此,一個迷你版的Linux誕生了,可以裝在自己移動U盤等裝置上面,這裡不做過多解釋

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-10/136169.htm


IT145.com E-mail:sddin#qq.com