Linux之手動編譯屬於自己的微型內核

對於Linux愛好者來說自己手動定做一個屬於自己的Linux系統是一件多麼酷的事。

那麼接下來我就給大家演示一下怎麼製作一個屬於自己的Linux吧。

 

爲什麼要製作屬於自己的Linux呢?

我們目前用的Linux系統都是從網上或者官方那裏得到的,是屬於一種通用版,並不是根據自己的硬件特性定製的,不能最大的發揮Linux系統的優越性。因此這是不能滿足我們這些Linux發燒友,製作屬於自己的Linux讓其發揮最大優越性能吧。

 

準備工作:我們製作的Linux是根據我們的硬件本身量身定製的,因此在製作前我們需要清楚的知道我們的目標主機(我們要安裝微型Linux的主機)的硬件信息,製作系統前我們需要在宿主機(製作Linux的主機)上完成對系統的製作

 

 

整理一下心情讓我們開始吧!!!

 

 

1、步驟規劃

   A、爲內核提供CPU+Memory+Disk

   B、提供文件系統

   C、提供bash

   D、提供init, --> bash

   E、提供輸入設備

   F、提供TCP/IP協議棧,網絡功能

 

一、查看設備硬件信息

[root@jsh ~]# cat /proc/cpuinfo       查看CPU信息
processor: 0
vendor_id: GenuineIntel
cpu family: 6
model: 42
model name: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz    酷睿i5-2450M的
stepping: 7
cpu MHz: 2494.379
cache size: 3072 KB
physical id: 0
siblings: 2
core id: 0
cpu cores: 2                                             雙核心
apicid: 0
initial apicid: 0
fpu: yes
fpu_exception: yes
cpuid level: 13
wp: yes
[root@jsh ~]# cat /proc/meminfo       查看內存信息
[root@jsh ~]# lspci                  查看橋設備信息
[root@jsh ~]# lsusb                  查看usb信息



下載內核源代碼:www.kernel.org

我們此次實驗使用的是3.13.6版本的內核源碼



二、爲目標磁盤創建文件系統

 

們製作的Linux系統首先是存放在宿主機的一塊硬盤上,製作好後把此硬盤給目標機,因此我們首先需要在宿主機上添加一塊硬盤然後對此硬盤創建文件系統。

 

添加硬盤步驟

wKiom1P5y_ijp4vAAAHLKm2-C04228.jpg

wKiom1P5zA3wAMFuAAEouahNQJw217.jpg

wKioL1P5zTmgpScMAAGJgJ4fteA976.jpg

wKioL1P5zV3An4zWAAE_n4flKGU599.jpg

wKiom1P5zFmzO3HTAAE4U-tIXr8933.jpg

注:添加完要重新啓動虛擬機纔會識別此硬盤

添加完成後接下來就是創建文件系統了。

 

[root@jsh ~]# fdisk /dev/sdb     看好自己添加的是哪一塊硬盤,此處我添加的是sbd
Command (m for help): n          創建分區
Command action
   e   extended
   p   primary partition (1-4)
P                              創建主分區
Partition number (1-4): 1           創建第一個主分區
First cylinder (1-2610, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +50M
給第一個主分區分配50M空間用來存放內核
Command (m for help): n           再創建一個分區
Command action
   e   extended
   p   primary partition (1-4)
P                              創建主分區
Partition number (1-4): 2           創建第二個主分區
First cylinder (8-2610, default 8): 
Using default value 8
Last cylinder, +cylinders or +size{K,M,G} (8-2610, default 2610): +512M
給第二個主分區分配512M空間來存放根文件系統
Command (m for help): w         保存並退出
The partition table has been altered!
 
Calling ioctl() to re-read partition table.
Syncing disks.
[root@jsh ~]# mke2fs -t ext4 /dev/sdb{1,2}    格式化sdb1和sdb2,文件系統爲ext4


創建兩個目錄,讓這兩個分區各自掛載

[root@jsh ~]# mkdir /mnt/{boot,sysroot}      在/mnt下創建boot和sysroot兩個目錄
[root@jsh ~]# mount /dev/sdb1 /mnt/boot/     把sdb1掛載至/mnt/boot/
[root@jsh ~]# mount /dev/sdb2 /mnt/sysroot/   把sdb2掛載至/mnt/sysroot/

爲目標機提供根文件系統

[root@jsh ~]# cd /mnt/sysroot/

注:在此目錄下我們有一個腳本,是用來複製程序以及程序所依賴的庫文件用的腳本

給大家提供這個腳本的代碼

[root@jsh sysroot]# vim bincp.sh
#!/bin/bash
#
target=/mnt/sysroot/
 
[ -d $target ] || mkdir $target
#!/bin/bash
#
target=/mnt/sysroot/
 
[ -d $target ] || mkdir $target
 
preCommand() {
    if which $1 &> /dev/null; then
        commandPath=`which --skip-alias $1`
        return 0
    else
        echo "No such command."
        return 1
    fi
}
 
commandCopy() {
    commandDir=`dirname $1`
    [ -d ${target}${commandDir} ] || mkdir -p ${target}${commandDir}
    [ -f ${target}${commandPath} ] || cp $1 ${target}${commandDir}
}
 
libCopy() {
    for lib in `ldd $1 | egrep -o "/[^[:space:]]+"`; do
        libDir=`dirname $lib`
        [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
        [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
    done
}
 
read -p "Plz enter a command: " command
 
until [ "$command" == 'quit' ]; do
 
  if preCommand $command ; then
    commandCopy $commandPath
    libCopy $commandPath
  fi
 
  read -p "Plz enter a command: " command
done

注:若複製此腳本的話那麼之前創建的文件路徑必須與我們之前創建的路徑一樣,否則此腳本執行時會報錯的。

[root@jsh sysroot]# chmod +x bincp.sh         給此腳本一個執行權限 
[root@jsh sysroot]# bash bincp.sh             執行此腳本
Plz enter a command: bash                   複製bash程序
Plz enter a command: cat                    複製cat命令
Plz enter a command: ls                     複製ls命令
Plz enter a command: ifconfig                複製ifconfig命令
Plz enter a command: quit                   退出
[root@jsh sysroot]#

爲目標機提供根下的目錄

[root@jsh sysroot]# mkdir -pv etc proc sys dev usr var tmp home root boot sbin




三、爲目標磁盤安裝grub

[root@jsh ~]# grub-install --root-directory=/mnt /dev/sdb
[root@jsh ~]# ls /mnt/boot/
grub  lost+found                      此時我們就能看到boot目錄下有一個grub目錄




四、編譯內核

 

然後我們給grub提供配置文件就行了,配置文件在內核源碼中,因此我們需要解壓內核源碼

wKiom1P5zXagZrvdAAFFhZJWQHk779.jpg

此內核是我之前下載好的

[root@jsh ~]# tar xf linux-3.13.6.tar.xz -C /usr/src/     我們把它解壓到/usr/src/下

wKiom1P5za_QKiJIAADGUtA05-k545.jpg

wKioL1P5zsjC49HZAAFPuEbUcS8422.jpg

wKiom1P5zbKj0tQmAAEJTMiZH8Q210.jpg

[root@jsh linux]# make menuconfig     執行此命令,去選擇我們用到的功能

注:執行此步驟會彈出一個圖形化界面,如果你的系統不支持圖形化操作請自行安裝開發環境

wKioL1P5zxfD7CSPAAMoXvT8-Eg173.jpg

wKiom1P5zgPTcOK2AAMVB8OkFvU627.jpg

wKioL1P5zx_S-IpZAAPseBS6UHE798.jpg

wKiom1P5zgrxEksjAAF_Lkvw95Q754.jpg

wKioL1P5z1TBUZJjAAQBlk2cnZM588.jpg

wKiom1P5zkGSdxF2AAMj-vxpQo8934.jpg

wKioL1P5z16iAxvZAAQGpzgadwU268.jpg

wKiom1P5zkrg7XMLAAIGnrZiX-M153.jpg

wKioL1P5z5KSHl1rAAR50pei7ic098.jpg

wKiom1P5zn6xgKdbAAMfLGmORjE542.jpg

wKioL1P5z5nSoPu8AAMf8ELrwnM559.jpg

wKiom1P5zoazB6VOAAOCHt13OWo686.jpg

接下來我們就該選磁盤功能了

wKioL1P50A6wQmLaAAMpJVaVSZw022.jpg

wKiom1P5zvmym5H9AAMZiWc0jU4592.jpg

wKioL1P50BaCuJ7MAAO2WIm4KFQ540.jpg

wKiom1P5zwKw5qlKAAN5XTQRylo259.jpg

wKioL1P50B_B_C1ZAAPRf4SP1vs791.jpg

wKiom1P5zwzx0idsAAL9GcFEwLc338.jpg

wKioL1P50CiDHnriAAM7C1TFi9g770.jpg

wKiom1P5zxay4nptAAO3yB504uA097.jpg

wKioL1P50DOjRO_aAAM07KstRPE417.jpg

wKiom1P5z1DjVEGXAAKxpGr4dKw237.jpg

wKioL1P50Gvi9Vi4AAM19b16ke8466.jpg

wKiom1P5z1aBb_GrAAK7yRzPjrY156.jpg

然後就可以保存退出了

[root@jsh linux]# make bzImage       編譯內核

注:編譯可能要花費一些時間,我們不防這會兒給提供一下grub配置文件

grub提供配置文件

[root@jsh ~]# cd /mnt/boot/grub
[root@jsh grub]# vim grub.conf
timeout=5
default=0
title ce shi linux (3.13.6)
        root (hd0,0)
        kernel /bzImage ro root=/dev/sda2 init=/bin/bash


然後我們再來看一下已經編譯好了

wKiom1P5z6DBD9OOAAEv9iPMseI776.jpg

然後把編譯好的內核放在我們之前創建的專門用於存放內核的目錄下

[root@jsh linux]# cp arch/x86/boot/bzImage /mnt/boot/
[root@jsh linux]# sync        然後同步一下
[root@jsh boot]# chmod +x /mnt/boot/bzImage    給執行權限

然後把宿主機掛起創建目標主機就可以測試我們製作的系統是否能用了。

創建目標虛擬機

wKiom1P50BKRoX9nAAGly4jsbUk068.jpg

wKioL1P50SvTkXV1AAFMjV7wuVI960.jpg

wKiom1P50BayKS3aAAFUmoVEYpE831.jpg

wKioL1P50S-yL48EAAErbjSVLVA078.jpg

wKioL1P50THSQA8SAAD96Fb5bwQ120.jpg

wKiom1P50BviDuZmAADpHvDPlrs038.jpg

wKiom1P50BziSb0KAAFvIHB4S3o573.jpg

wKioL1P50Tag003xAAGEJBjw_sM598.jpg

wKiom1P50CDji9KHAAEF1PiHLOg385.jpg

wKioL1P50TrAdXhWAAG7sFNIN1E946.jpg

wKiom1P50CTgVL16AAEuZ9HpMnI564.jpg

wKioL1P50T2zz4ksAAFZfjZLmq8471.jpg

wKioL1P50T6BS_RTAAEiYdpkxWg282.jpg

wKiom1P50CiToKTEAAOcVZtRDSA641.jpg

此時我們的系統已經能夠正常的啓動了,但是由於我們沒有做好輸入設備的驅動,這裏的鼠標鍵盤是不能用的,接下來我們就開始配置內核的輸入設備驅動吧。

 

 

 

首先把目標機關機,然後再次開啓宿主機,(注:之前做目標機測試時我們要把宿主機掛起,現在我們再啓用宿主機

 

在宿主機下:

[root@jsh ~]# cd /usr/src/linux
[root@jsh linux]# make menuconfig

wKiom1P50ILxviB8AAKL3mW4Tp0038.jpg

wKiom1P50ISxaLarAALttMrp3yI198.jpg

wKioL1P50Z7RDiyJAAL-2e8l6bc488.jpg

wKiom1P50IrTsTk8AAMFJBzG7SY550.jpg

wKiom1P50I6A6lRNAAQKcKM0LAc860.jpg

wKioL1P50arQbBnJAAOkhKjG2d0130.jpg

然後保存退出

[root@jsh linux]# make -j 3    編譯
[root@jsh linux]# cp arch/x86/boot/bzImage /mnt/boot/
cp: overwrite `/mnt/boot/bzImage'? y           覆蓋原文件
[root@jsh linux]# sync                      同步

這就完成了鍵盤鼠標的驅動,如果這樣啓動的話還是有一個問題,我們需要讓其啓動時自動運行init,因此我們需要在/sbin下編輯文件

[root@jsh linux]# cd /mnt/sysroot/sbin
[root@jsh sbin]# vim init
#!/bin/bash
 
echo -e "Welcom to \033[32mce shi\033[34mlinux."
mount -n -t proc proc /proc
mount -n -t sysfs sysfs /sys
mount -n -o remount,rw /dev/sda2
/bin/bash
[root@jsh sbin]# chmod +x init       給一個執行權限
[root@jsh sbin]# vim /mnt/boot/grub/grub.conf

wKiom1P50Oby6pxSAABjJYA3xJQ803.jpg

然後我們需要移植mount命令

[root@jsh ~]# bash bincp.sh        bincp.sh這個腳本要實現創建
Plz enter a command: mount        移植mount命令
Plz enter a command: umount       移植umount命令
Plz enter a command: quit          退出
[root@jsh ~]#

好了,這樣我們就可以啓動一下試試了,首先掛起宿主機。然後開啓目標機

wKioL1P50izDoZrGAAKdMNEthdA951.jpg

Ok這樣就啓動了,哈哈只不過字體顏色設置的有點奇怪,嘿嘿。

wKiom1P50TKhdDLGAAIP9PmhO08083.jpg

包括我們移植的命令也可以用哦,是不是有點小激動呢,但是總覺得怪怪的,跟我們的正常的系統還是有很多的不一樣。

 

但是這樣還有一個問題,我們可以看一下我們的設備文件

wKioL1P50mWD7A0pAAAeGzOA5a8453.jpg

我們的dev下是空的,那怎麼識別我們的sda1sda2呢?

注:此時各設備文件是在內核的內存中的

 

 

我們還回到宿主機上

[root@jsh ~]# cd /usr/src/linux
[root@jsh linux]# make menuconfig

wKiom1P50ZiynOB8AAJkQWLmImE051.jpg

wKioL1P50rLgjcOAAALVE3UYXCY403.jpg

wKiom1P50Z2gL3H5AAKWMWkMC7I200.jpg

然後保存退出

[root@jsh linux]# make -j 3
[root@jsh linux]# cp arch/x86/boot/bzImage /mnt/boot/
cp: overwrite `/mnt/boot/bzImage'? y

編輯文件手動掛載

[root@jsh ~]# vim /mnt/sysroot/sbin/init

wKioL1P50uqx0_Y5AACdalR1ulM404.jpg

添加紅色方框內容

 

好我們再來試一下,看看上邊的設備文件有沒有掛載上,首先掛起宿主機,然後再開啓目標機。

wKiom1P50fSC6QlZAAJF5fq0XF0861.jpg

OK!成功了,呵呵怎麼樣是不是小有成就呢。

 

至此,我們的六個步驟中的前五個步驟都已經完成了,接下來就是最後一步了,配置網絡功能。

 

在宿主機下

[root@jsh ~]# cd /usr/src/linux
[root@jsh linux]# make menuconfig

wKioL1P501qwPe7mAAJ6oR22RXI520.jpg

wKioL1P5012CNkfqAAJ2DhD-Ro8220.jpg

wKiom1P50kiBBH5-AALtfXGlAYs714.jpg

wKioL1P502LDymMJAANDcXfml7k639.jpg

wKiom1P50k3jFPIRAAKVqCELkrs025.jpg

wKioL1P502jCrQZhAAL8YXiHM1E426.jpg

wKiom1P50lOyQrdHAANeuRZf6XI678.jpg

wKioL1P5027xnG5QAANHQ0gobVg656.jpg

wKiom1P50lnTZQBqAAMhor0kQ3o070.jpg

然後保存退出

[root@jsh linux]# make -j 3
[root@jsh linux]# cp arch/x86/boot/bzImage /mnt/boot/
cp: overwrite `/mnt/boot/bzImage'? y

移植一下網絡相關的命令

[root@jsh ~]# bash bincp.sh 
Plz enter a command: route
Plz enter a command: netstat
Plz enter a command: ping
Plz enter a command: quit

然後就能掛起宿主機,啓動目標機了

wKioL1P507rDxyJmAAIcbhzVmQg503.jpg


OK是不是很有成就感!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章