天天看點

一步步手動建構一個小的linux系統

前提:

1、一個作為主控端的Linux;本文使用的是Redhat Enterprise Linux 5.8;

2、在主控端上提供一塊額外的硬碟座位新系統的存儲盤,為了降低複雜度,這裡添加使用一塊IDE接口的新硬碟;

3、linux核心源碼,busybox源碼;本文使用的是目前最新版的Linux-2.6.38.5和busybox-1.20.2。

一、為系統上的新硬碟建立分區,這裡根據需要先建立一個大小為100M的主分區作為建立系統的Boot分區和一個512M的分區作為目标系統(即正在建構的新系統,後面将沿用此名稱)的根分區;100M的分區格式化後将其挂載至/mnt/boot目錄下;512M的分區格式化後将挂載至/mnt/sysroot目錄;

說明:

1、此處的boot和sysroot的挂載點目錄名稱盡量不要修改,尤其是boot目錄,否則您必須保證後面的許多步驟都做了相應的改動;

2、建立系統的boot目錄也可以跟根目錄在同一個分區,這種方式比獨立分區還要簡單些,是以這裡将不對此種方法再做出說明;

二、編譯核心源代碼,為新系統提供一個所需的核心(本例中的源代碼包都位于/usr/src目錄中)

<code># cd  /usr/src</code>

<code># tar jxvf linux-2.6.38.5.tar.bz2</code>

<code># ln  -sv  linux-2.6.38.5  linux</code>

<code># cd linux</code>

然後下載下傳ftp://172.16.0.1/pub/Sources/kernel/kernel-2.6.38.1-i686.cfg至目前目錄中,并重命名為.config。

<code># make menuconfig</code>

根據您的實際和規劃選擇所需要的功能;本執行個體計劃制作一個具有網絡的功能的微型linux且不打算使用核心子產品,是以,這裡選擇把本機對應的網卡驅動直接編譯進了核心。作者使用的是vmware Workstation虛拟機,是以,所需的網上驅動是pcnet32的,其它的均可按需要進行選擇。選擇完成後需要儲存至目前目錄下.config檔案中。

<code># make  SUBDIR=arch/</code>

<code># cp arch/x86/boot/bzImage  /mnt/boot</code>

三、編譯busybox

<code># cd /usr/src</code>

<code># tar  -jxvf  busybox-1.20.2.tar.bz2</code>

<code># cd  busybox-1.20.2</code>

<code># mkdir include/mtd </code>

<code># cp  /usr/src/linux/include/mtd/ubi-user.h  include/mtd/</code>

1、此處需要選擇 Busybox Settings --&gt; Build Options --&gt;  Build BusyBox as a static binary (no shared libs),這樣可以把Busybox編譯成一個不使用共享庫的靜态二進制檔案,進而避免了對主控端的共享庫産生依賴;但你也可以不選擇此項,而完成編譯後把其依賴的共享庫複制至目标系統上的/lib目錄中即可;這裡采用後一種辦法。

2、修改安裝位置為/mnt/sysroot;方法為:Busybox Settings --&gt; Installation Options --&gt; (./_install) BusyBox installation prefix,修改其值為/mnt/sysroot。

<code># make  install</code>

安裝後的檔案均位于/mnt/sysroot目錄中;但為了建立initrd,并實作讓其啟動以後将真正的檔案系統切換至目标系統分區上的rootfs,您還需要複制一份剛安裝在/mnt/sysroot下的busybox至另一個目錄,以實作與真正的根檔案系統分開制作。我們這裡選擇使用/mnt/temp目錄;

<code># mkdir -pv /tmp/busybox</code>

<code># cp -r /mnt/sysroot/*  /tmp/busybox</code>

四、制作initrd

<code># cd  /tmp/busybox</code>

1、建立rootfs:

<code># mkdir -pv  proc  sys  etc/init.d  tmp  dev  mnt/sysroot</code>

2、建立兩個必要的裝置檔案:

<code># mknod  dev/console  c  5  1</code>

<code># mknod  dev/null  c  1  3</code>

3、為initrd制作init程式,此程式的主要任務是實作rootfs的切換,是以,可以以腳本的方式來實作它:

<code># rm  linuxrc</code>

<code># vim  init</code>

添加如下内容:

<code>#!/bin/sh</code>

<code>mount</code> <code>-t proc proc </code><code>/proc</code>

<code>mount</code> <code>-t sysfs sysfs </code><code>/sys</code>

<code>insmod </code><code>/lib/modules/jbd</code><code>.ko</code>

<code>insmod </code><code>/lib/modules/ext3</code><code>.ko</code>

<code>mdev -s</code>

<code>mount</code> <code>-t ext3 </code><code>/dev/hda2</code>  <code>/mnt/sysroot</code>

<code>exec</code>  <code>switch_root  </code><code>/mnt/sysroot</code>  <code>/sbin/init</code>

給此腳本執行權限:

<code>chmod</code>  <code>+x  init</code>

4、制作initrd

<code># find  .  | cpio  --quiet  -H newc  -o  | gzip  -9 -n &gt; /mnt/boot/initrd.gz</code>

五、建立真正的根檔案系統

<code># cd  /mnt/sysroot</code>

<code># mkdir -pv  proc  sys  etc/rc.d/init.d  tmp  dev/pts  boot  var/log  usr/lib</code>

3、建立系統初始化腳本檔案

<code># vim  etc/rc.d/rc.sysinit</code>

 #!/bin/sh

<code>echo</code> <code>-e </code><code>"\tWelcome to  \033[31msunshine\033[0m Linux"</code>

<code>echo</code> <code>-e </code><code>"Remounting the root filesystem ..."</code>

<code>mount</code> <code>-o  remount,rw  / </code>

<code>echo</code> <code>-e </code><code>"Creating the files of device ..."</code>

<code>mdev -s </code>

<code>echo</code> <code>-e </code><code>"Mounting the filesystem ..."</code>

<code>mount</code> <code>-a</code>

<code>swapon -a</code>

<code>echo</code> <code>-e </code><code>"Starting the log daemon ..."</code>

<code>syslogd</code>

<code>klogd</code>

<code>echo</code> <code>-e </code><code>"Configuring loopback interface ..."</code>

<code>ifconfig</code>  <code>lo  127.0.0.1</code><code>/24</code>

<code>ifconfig</code> <code>eth0 172.16.100.9</code><code>/16</code>

<code># END</code>

而後讓此腳本具有執行權限:

<code>chmod</code> <code>+x  etc</code><code>/init</code><code>.d</code><code>/rc</code><code>.sysinit</code>

4、配置init及其所需要inittab檔案

<code># rm  -f  linuxrc</code>

為init程序提供配置檔案:

<code># vim  etc/inittab</code>

<code>::sysinit:</code><code>/etc/rc</code><code>.d</code><code>/rc</code><code>.sysinit</code>

<code>console::respawn:-</code><code>/bin/sh</code>

<code>::ctrlaltdel:</code><code>/sbin/reboot</code>

<code>::</code><code>shutdown</code><code>:</code><code>/bin/umount</code> <code>-a -r</code>

5、為系統準備一個“檔案系統表”配置檔案/etc/fstab

<code># vim  etc/fstab</code>

<code>sysfs                   </code><code>/sys</code>                    <code>sysfs   defaults        0 0</code>

<code>proc                    </code><code>/proc</code>                   <code>proc    defaults        0 0</code>

<code>/dev/hda1</code>               <code>/boot</code>                   <code>ext3    defaults        0 0</code>

<code>/dev/hda2</code>               <code>/                       ext3    defaults        1 1</code>

6、由于在rc.sysinit檔案中啟動了日志程序,是以系統在運作中會産生大量日志并将其顯示于控制台;這将會經常性的打斷正在進行的工作,為了避免這種情況,我們這裡為日志程序建立配置檔案,為其指定将日志發送至/var/log/messages檔案;

<code># vim  etc/syslog.conf</code>

添加如下一行:

<code>*.info    </code><code>/var/log/messages</code>

六、好了,至此一個簡易的基于記憶體運作的小系統已經建構出來了,我們接下來為此系統建立所需的引導程式

<code># grub-install  --root-directory=/mnt  /dev/hda</code>

說明:此處的/dev/hda為目标系統所在的那塊新磁盤;

接下來為grub建立配置檔案:

<code># vim  /mnt/boot/grub/grub.conf</code>

添加類似如下内容:

<code>default        0</code>

<code>timeout        3</code>

<code>color    light-green</code><code>/black</code> <code>light-magenta</code><code>/black</code>

<code>title    Sunshine Linux (2.6.38.5)</code>

<code>    </code><code>root (hd0,0)</code>

<code>    </code><code>kernel </code><code>/bzImage</code> <code>ro root=</code><code>/dev/hda2</code> <code>quiet</code>

<code>    </code><code>initrd </code><code>/initrd</code><code>.gz</code>

接下來将此塊硬碟接入一個新的主機(這裡使用的是虛拟機),啟動一下并測試使用。

七、為新建構的ToyLinux啟用虛拟控制台

這個可以通過主控端來實作,也可以直接啟動剛建構成功的小Linux進行配置。我們這裡采用通過主控端的方式(重新啟動主控端):

<code># cd /mnt/sysroot</code>

将 etc/inittab檔案改為如下内容:

<code>::sysinit:</code><code>/etc/init</code><code>.d</code><code>/rc</code><code>.sysinit</code>

<code>tty1::askfirst:</code><code>/bin/sh</code>

<code>tty2::askfirst:</code><code>/bin/sh</code>

<code>tty3::askfirst:</code><code>/bin/sh</code>

<code>tty4::askfirst:</code><code>/bin/sh</code>

<code>tty5::askfirst:</code><code>/bin/sh</code>

<code>tty6::askfirst:</code><code>/bin/sh</code>

好了,接下來就可以測試驗正六個虛拟控制台的使用了。

八、盡管上述第七步已經實作了虛拟控制台,但其仍是直接進入系統,且系統沒有使用者帳号等安全設施,這将不利于系統的安全性。是以,接下來的這步實作為系統添加使用者帳号(這裡仍然基于主控端實作)。

1、為目标主機建立passwd帳号檔案

<code># vim etc/passwd</code>

<code>root:x:0:0::</code><code>/root</code><code>:</code><code>/bin/sh</code>

而後為root使用者建立“家”目錄:

<code># mkdir root</code>

2、為目标主機建立group帳号檔案

<code># vim  etc/group</code>

<code>root:x:0:</code>

3、為目标主機建立shadow影子密碼檔案,這裡采用直接複制主控端的shadow檔案中關于root密碼行的行來實作

<code># grep  "^root"  /etc/shadow  &gt; etc/shadow</code>

注:等目标主機啟動時,root使用者的密碼也是主控端的root使用者的密碼。您可以在目标主機啟動以後再動手更改root使用者的密碼。

4、将 etc/inittab檔案改為如下内容:

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty1</code>

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty2</code>

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty3</code>

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty4</code>

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty5</code>

<code>::respawn:</code><code>/sbin/getty</code> <code>9600 tty6</code>

好了,接下來就可以重新啟動目标主機進行驗正了。

九、在系統登入時提供banner資訊

這個可以通過主控端來實作,也可以直接在目标主機上進行配置。這裡采用直接在目标主機上配置的方式:

<code># vi  /etc/issue</code>

<code>Welcome to sunshine Linux...</code>

<code>Kernel \r</code>

注:這裡的内容可以根據你的需要進行修改。

十、在系統啟動時為系統提供主機名稱:

1、建立儲存主機名稱的配置檔案

<code># mkdir /etc/sysconfig</code>

<code># vi  /etc/sysconfig/network</code>

<code>HOSTNAME=marion.example.com</code>

2、編輯系統初始化腳本,實作開機過程中設定主機名稱

<code># vi /etc/init.d/rc.sysinit</code>

在檔案尾部添加如下行:

<code>HOSTNAME=</code>

<code>[ -e  </code><code>/etc/sysconfig/network</code>  <code>&amp;&amp; -r </code><code>/etc/sysconfig/network</code> <code>] &amp;&amp; </code><code>source</code> <code>/etc/sysconfig/network</code>

<code>[ -z ${HOSTNAME} ] &amp;&amp; HOSTNAME=</code><code>"localhost"</code>

<code>/bin/hostname</code>  <code>${HOSTNAME}</code>

十一、通過dropbear為系統提供ssh遠端連接配接服務

注:以下過程在主控端上實作。

1、編譯安裝dropbear

<code># tar xf dropbear-2013.56.tar.bz2 </code>

<code># cd dropbear-2013.56</code>

<code># ./configure </code>

<code># make</code>

<code># make install</code>

2、移植dropbear至目标系統

移植二進制程式及其依賴的庫檔案,方能實作其在目标系統上正常運作。建議使用腳本進行(這裡将其儲存為bincp.sh),其會自動移植指定的指令及依賴的庫檔案。

<code>#!/bin/bash</code>

<code>#</code>

<code>read</code> <code>-t 30 -p </code><code>"Target System Directory[/mnt/sysroot]: "</code> <code>DEST</code>

<code>DEST=${DEST:-</code><code>/mnt/sysroot</code><code>}</code>

<code>libcp() {</code>

<code>  </code><code>LIBPATH=${1%/*}</code>

<code>  </code><code>[ ! -d $DEST$LIBPATH ] &amp;&amp; </code><code>mkdir</code> <code>-p $DEST$LIBPATH</code>

<code>  </code><code>[ ! -e $DEST${1} ] &amp;&amp; </code><code>cp</code> <code>$1 $DEST$LIBPATH &amp;&amp; </code><code>echo</code> <code>"copy lib $1 finished."</code>

<code>}</code>

<code>bincp() {</code>

<code>  </code><code>CMDPATH=${1%/*}</code>

<code>  </code><code>[ ! -d $DEST$CMDPATH ] &amp;&amp; </code><code>mkdir</code> <code>-p $DEST$CMDPATH</code>

<code>  </code><code>[ ! -e $DEST${1} ] &amp;&amp; </code><code>cp</code> <code>$1 $DEST$CMDPATH</code>

<code>  </code><code>for</code> <code>LIB </code><code>in</code>  <code>`ldd $1 | </code><code>grep</code> <code>-o </code><code>"/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"</code><code>`; </code><code>do</code>

<code>    </code><code>libcp $LIB</code>

<code>  </code><code>done</code>

<code>read</code> <code>-p </code><code>"Your command: "</code> <code>CMD</code>

<code>until</code> <code>[ $CMD == </code><code>'q'</code> <code>]; </code><code>do</code>

<code>   </code><code>! </code><code>which</code> <code>$CMD &amp;&amp; </code><code>echo</code> <code>"Wrong command"</code> <code>&amp;&amp; </code><code>read</code> <code>-p </code><code>"Input again:"</code> <code>CMD &amp;&amp; </code><code>continue</code>

<code>  </code><code>COMMAND=` </code><code>which</code> <code>$CMD | </code><code>grep</code> <code>-</code><code>v</code> <code>"^alias"</code> <code>| </code><code>grep</code> <code>-o </code><code>"[^[:space:]]\{1,\}"</code><code>`</code>

<code>  </code><code>bincp $COMMAND</code>

<code>  </code><code>echo</code> <code>"copy $COMMAND finished."</code>

<code>  </code><code>read</code> <code>-p </code><code>"Continue: "</code> <code>CMD</code>

<code>done</code>

接下來運作此腳本,分别輸入dropbear、dropbearkey和dbclient即可;這些指令會被存儲于目标系統的/usr/local/sbin或/usr/local/bin目錄中。

3、為遠端登入的使用者提供僞終端裝置檔案

編輯/mnt/sysroot/etc/fstab,添加如下一行:

<code>devpts </code><code>/dev/pts</code> <code>devpts mode=620 0 0</code>

建立所需要的目錄:

<code># mkdir /mnt/sysroot/dev/pts</code>

4、為目标系統的dropbear生成主機密鑰

預設情況下,dropbear到/etc/dropbear目錄中查找使用的rsa格式主機密鑰(預設名稱為dropbear_rsa_host_key)和dss格式的主機密鑰(預設名稱為dropbear_dss_host_key)。其中,rsa格式可使用不同長度的密鑰,但dss格式隻使用1024位的密鑰。

<code># mkdir /mnt/sysroot/etc/dropbear</code>

<code># dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048</code>

<code># dropbearkey -t rsa -f /etc/dropbear/dropbear_dss_host_key</code>

在生成rsa格式的key時,其長度指定部分-s 2048可以省略,也可以為其指定為其它長度,但長度需要為8的整數倍。

說明:此步驟也可以在目标主機上進行,但路徑要做相應的修改。

5、定義安全shell

安全起見,dropbear預設情況下僅允許其預設shell出現在/etc/shells檔案中的使用者遠端登入,是以,這裡還需要建立/etc/shells檔案,并添加所有允許的shell。

<code># cat &gt;&gt; /mnt/sysroot/etc/shells &lt;&lt; EOF</code>

<code>/bin/sh</code>

<code>/bin/ash</code>

<code>/bin/hush</code>

<code>/bin/bash</code>

<code>EOF</code>

6、為目标主機提供網絡服務轉換機制

在主控端上使用預設選項編譯的dropbear将依賴nsswitch實作使用者名稱解析,是以,還需要為目标主機提供nss相關的庫檔案及配置檔案。

<code># cat &gt;&gt; /mnt/sysroot/etc/nsswitch.conf &lt;&lt; EOF</code>

<code>passwd</code><code>:     files</code>

<code>shadow:     files</code>

<code>group:      files</code>

<code>hosts:      files dns</code>

複制所需要的庫檔案:

<code># cp -d /lib/libnss_files*  /mnt/sysroot/lib/</code>

<code># cp -d /usr/lib/libnss3.so /usr/lib/libnss_files.so /mnt/sysroot/usr/lib/</code>

7、測試

啟動目标主機,設定好網絡屬性後,使用如下指令啟動dropbear服務即可。

<code># /usr/local/sbin/dropbear</code>

接下來就可以遠端進行連接配接測試了。

十二、通過nginx提供web服務

1、在主控端編譯安裝nginx-1.2.5

<code># tar nginx-1.2.5.tar.gz</code>

<code># cd nginx-1.2.5</code>

<code># ./configure --prefix=/usr/local --conf-path=/etc/nginx/nginx.conf  --error-log-path=/var/log/nginx/error.log --user=nginx --group=nginx --http-log-path=/var/log/nginx/access.log  --without-pcre --without-http_rewrite_module --without-http_geo_module --without-http_fastcgi_module  --without-http_uwsgi_module  --without-http_scgi_module --without-http_memcached_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module  --without-http_upstream_keepalive_module --http-log-path=/var/log/nginx</code>

2、移植nginx至目标系統

(1) 移植二進制程式及其依賴的庫檔案,方能實作其在目标系統上正常運作。建議使用前面的bincp.sh腳本進行。

(2) 移植配置檔案至目标系統

<code># mkdir  /mnt/sysroot/etc/nginx/</code>

<code># cp /etc/nginx/{nginx.conf,mime.types}  /mnt/sysroot/etc/nginx/</code>

(3) 移植測試頁面至目标系統,當然,也可以不采用下面的步驟而在目标系統上直接建立。

<code># mkdir /mnt/sysroot/usr/local/</code>

<code># cp -r /usr/local/html  /mnt/sysroot/usr/local/</code>

3、測試

啟動目标主機,首先配置好網絡屬性,并使用adduser為其添加nginx使用者和nginx組。

然後使用如下指令啟動nginx,即可通過浏覽器測試通路。

<code># /usr/local/nginx</code>

<code></code>

本文轉自 SoulMio 51CTO部落格,原文連結:http://blog.51cto.com/bovin/1860765,如需轉載請自行聯系原作者