Linux kernel的定製與微型linux系統實現

Linux kernel的定製與微型linux系統實現


實驗與實驗環境介紹

     通過vmware workstation10 軟件,實現inux kernel的定製,並用這個定製的kernel 結合 busybox做成一個微型的linux系統,同時添加dropbear實現sshd服務。

     實驗環境:


    實驗過程簡單描述:

    1.1)在宿主機Test02上添加2G全新磁盤TTT.vmdk(.vmdk是vmware 虛擬機軟件的專用的磁盤文件格式),劃分爲2個分區:分區A掛載至宿主機/mnt/boot目錄下(掛載點目錄名一定爲boot,牽涉到grub程序的安裝),用於安裝grub和放置kernel,用於啓動分區。分區B掛載至宿主機/mnt/sysroot下,給其移植編譯好busybox,dropbear,nginx和相應的啓動腳本文件。

      wKioL1VgMtKicuEgAAKGmwYzGeE144.jpg

    

    

      1.2)掛起宿主機Test02,讓測試機Test64加載TTT.vmdk磁盤做爲系統盤啓動。

wKioL1VgNNeT644QAAI84X2XLhc274.jpg

    1.3)檢查測試機Test64上linux是否正常啓動,sshd和nginx是否提供服務。

    

    實驗可能會出現的問題與疑問:

     上述TTT.vmdk磁盤在2個虛擬機上都被加載使用,在2臺機器間測試切換時,會出現磁盤文件系統錯誤,需重做分區文件系統,當然做好使用cpio命令將已有數據copy出來,在下文第七項中提供有恢復文件系統的腳本。

      因爲Test02與Test都是同一個vmware workstation軟件虛擬出的機器,因此不存在硬件平臺差異,不存在需要交叉編譯的情況,應用程序可直接互相移植使用。


    

 centos 6.6上系統的啓動流程

      主板POST加電自檢

      根據BIOS中boot sequence的設定尋找第一可啓動設備

      啓動第一個可引導啓動設備的MBR 中的bootloader(通常爲grub,完成1,1.5,2三個部分的加載)

      加載並展開 kernel,根據ramdisk的協助,完成根文件系統的只讀加載,識別和啓動硬件         

      啓動第一個系統進程/sbin/init,設定默認運行級別,使用/etc/rc.d/rc.sysinit腳本進行系統初始化   

      分別關閉和啓動對應級別的所有服務

      啓動字符終端

      啓動圖形終端(如果默認級別爲5

      顯示登錄提示;         

        注意:

            (1) CentOS 6的init程序爲upstart,其配置文件爲/etc/init/*.conf;此些配置遵循upstart語法格式進行編程; 

            (2) CentOS 6的服務控制事實上大多數並沒有使用upstart腳本來控制,而依然使用的是SysV風格的腳本;   


       在這個實驗中驗證2.3)~2.9)的過程。


啓動分區設置:

    3.1)在宿主機Test02上對TTT.vmdk磁盤進行分區和格式化

    wKiom1VgN6Pjyl0jAATF6FiMddI467.jpg


[root@Test02 ~]# fdisk /dev/sdb

wKiom1VgOEbTgefoAAKDFtF0jrE628.jpg

分別格式化爲ext4 文件系統:

      **一定要記住這裏的文件系統類型,後邊指定kernel支持的文件系統類型時要用到。

[root@Test02 ~]# mke2fs -t ext4 /dev/sdb1

[root@Test02 ~]# mke2fs -t ext4 /dev/sdb2

wKioL1VgOtyAyL1NAAJS99qqakc639.jpg


    3.2)建立掛載點:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#建立掛載點/mnt/boot用於掛載/dev/sdb1

#/dev/sdb1是用於測試機Test64的啓動分區使用,需要安裝grub,故這裏的掛載點名必須爲boot。

#/dev/sdb2是用於測試機Test64的根分區使用。

[root@Test02 ~]# mkdir /mnt/{boot,sysroot}

[root@Test02 ~]# mount -t ext4 /dev/sdb1 /mnt/boot

[root@Test02 ~]# mount -t ext4 /dev/sdb2 /mnt/sysroot/

[root@Test02 ~]# tree /mnt

/mnt

├── boot

│   └── lost+found

└── sysroot

    └── lost+found

4 directories, 0 files

[root@Test02 ~]#


    3.3)給/dev/sdb1安裝grub

1

2

3

4

5

6

7

8

9

10

[root@Test02 ~]# 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@Test02 ~]#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@Test02 ~]# tree /mnt/boot

/mnt/boot

├── grub

│   ├── device.map

│   ├── e2fs_stage1_5

│   ├── fat_stage1_5

│   ├── ffs_stage1_5

│   ├── iso9660_stage1_5

│   ├── jfs_stage1_5

│   ├── minix_stage1_5

│   ├── reiserfs_stage1_5

│   ├── stage1

│   ├── stage2

│   ├── ufs2_stage1_5

│   ├── vstafs_stage1_5

│   └── xfs_stage1_5

└── lost+found

2 directories, 13 files

[root@Test02 ~]#

到此刻啓動分區還是不完整的因爲缺少kernel和grub的啓動配置文件。


定製kernel:

    4.1)指定定製思路

      在這個實驗中將kernel的必要功能直接做進內核,而不是將功能做成模塊。暫時在微型linux系統中用不到的功能暫且不做任何處理。

      這樣在啓動微型linux時就不需要ramdisk給kernel提供支持。

    

    4.2)觀察宿主機硬件平臺類型

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

[root@Test02 linux]# lspci | egrep --color '(Ethernet|SCSI|PCI)'

00:01.0 PCI bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (rev 01)

00:10.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)

00:11.0 PCI bridge: VMware PCI bridge (rev 02)

00:15.0 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.1 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.2 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.3 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.4 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.5 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.6 PCI bridge: VMware PCI Express Root Port (rev 01)

00:15.7 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.0 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.1 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.2 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.3 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.4 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.5 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.6 PCI bridge: VMware PCI Express Root Port (rev 01)

00:16.7 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.0 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.1 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.2 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.3 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.4 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.5 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.6 PCI bridge: VMware PCI Express Root Port (rev 01)

00:17.7 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.0 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.1 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.2 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.3 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.4 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.5 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.6 PCI bridge: VMware PCI Express Root Port (rev 01)

00:18.7 PCI bridge: VMware PCI Express Root Port (rev 01)

02:00.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)

02:01.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)

02:02.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)

02:03.0 Multimedia audio controller: Ensoniq ES1371 / Creative Labs CT2518 [AudioPCI-97] (rev 02)

 

#可以觀察到網卡爲Inter Gigabit Ethernet

#SCSI控制器類型爲:LSI,MPT

#總線爲PCI總線


需要上述觀察結果制定出kernel支持的功能:

      將kernel功能直接做進內核

      CPU類:

           64位kernel

           指定cpu類型

            支持內核模塊卸載

      總線類:

              總線中支持PCI總線 

       對設備的支持:

             支持scsi驅動和scsi硬盤

             支持Fusion MPT device

             支持鍵盤和鼠標做爲輸入設備

             支持USB2.0功能

       對文件系統和二進制程序支持:

              支持ext4文件系統

               支持ELF格式的二進制文件

       對網絡的支持:

              支持TCP/IP協議棧

               支持inter Gigabit網卡

      

 清空kernel默認的設定,所需功能挨個定製

[root@Test02 linux]# make allnoconfig

  HOSTCC  scripts/basic/fixdep

  HOSTCC  scripts/kconfig/conf.o

  SHIPPED scripts/kconfig/zconf.tab.c

  SHIPPED scripts/kconfig/zconf.lex.c

  SHIPPED scripts/kconfig/zconf.hash.c

  HOSTCC  scripts/kconfig/zconf.tab.o

  HOSTLD  scripts/kconfig/conf

scripts/kconfig/conf --allnoconfig Kconfig

#

# configuration written to .config

#

[root@Test02 linux]#

#要保證宿主機上已安裝有下列開發組件:

    "Server Platform Development"

    "Development tools"



 使用tab鍵選擇-->save保存設定

 使用tab鍵選擇-->exit選擇退出

1

2

3

4

5

6

7

#進行編譯,保存爲bzip2壓縮的文件,名爲bzImage

[root@Test02 linux]# make bzImage

Setup is 13628 bytes (padded to 13824 bytes).

System is 2092 kB

CRC 4e20c446

Kernel: arch/x86/boot/bzImage is ready  (#1)

[root@Test02 linux]#

         4.4)複製內核至/mnt/boot目錄下並提供grub文件

1

2

3

4

5

6

7

8

9

10

11

[root@Test02 linux]# cp -a arch/x86/boot/bzImage  /mnt/boot/

[root@Test02 linux]# cd /mnt/boot

[root@Test02 boot]# ls

bzImage  grub  lost+found

[root@Test02 boot]# cd grub/

[root@Test02 grub]# vim grub.conf

timeout=3

default=0

title  PirateLi

        root (hd0,0)

        kernel /bzImage ro root=/dev/sda2 init=/bin/bash

        4.5)提供/mnt/sysroot下的必要的目錄和程序用於測試內核

1

2

3

4

5

6

7

8

9

10

11

[root@Test02 sysroot]# pwd/mnt/sysroot

2

3

4

5

6

7

8

9

10

11

12

13

[root@Test02 sysroot]# vi /mnt/sysroot/sbin/init

#!/bin/bash

echo -e "\tWeclome to \033[31;1mPirateLi Home\033[0m"

mount -n -t proc proc /proc

mount -n -t sysfs sysfs /sys

mount -n -t devtmpfs none /dev/

mount -n -o remount,rw /dev/sda2 /

/bin/bash

[root@Test02 sysroot]# chmod +x /mnt/sysroot/sbin/init

[root@Test02 sysroot]# sync

[root@Test02 sysroot]# sync

[root@Test02 sysroot]# sync

[root@Test02 sysroot]# sync

        4.6)掛起宿主機,啓動測試機並觀察

*注意不要在宿主機和測試機之間切換過快

wKiom1VgVy_RzunDAAN5JMuVG8Q893.jpg

 但是不能通過命令關機,只能強制關機


五 編譯busybox提供微linux的'身體'

    5.1)安裝glibc-static和glibc-util

#不安裝這兩個包很難講程序編譯爲靜態連接庫文件

1

[root@Test02 source]# yum -y install glibc-static glibc-utils

 

    5.2)編譯busybox

*注意要將busybox依賴的庫文件編譯爲靜態鏈接庫

1

2

3

4

5

6

[root@Test02 source]# tar -xf busybox-1.22.1.tar.bz2 

[root@Test02 source]# cd busybox-1.22.1[root@Test02 busybox-1.22.1]# make menuconfig

Busybox Settings

    -->Build Options

        --->[*]Build BusyBox as a static binary (no shared libs)

[root@Test02 busybox-1.22.1]# make && make install

**這樣的話busybox默認安裝在解壓目錄的_install中

1

2

3

[root@Test02 busybox-1.22.1]# ls _install/

bin  linuxrc  sbin  usr

[root@Test02 busybox-1.22.1]#

    5.3)清整/mnt/sysroot

1

2

3

4

5

6

7

8

9

10

#清理/mnt/sysroot

[root@Test02 mnt]# pwd

/mnt

[root@Test02 mnt]# fuser -km sysroot

/sysroot/:             2242c

[root@Test02 mnt]# umount sysroot/

[root@Test02 mnt]# mke2fs -t ext4 /dev/sdb2

[root@Test02 mnt]# mount /dev/sdb2 /mnt/sysroot/

[root@Test02 sysroot]# ls

lost+found

1

2

3

4

5

6

#複製busybox至/mnt/sysroot下並創建不存在的目錄

[root@Test02 sysroot]# cp -a /root/source/busybox-1.22.1/_install/* .

[root@Test02 sysroot]# ls

bin  linuxrc  lost+found  sbin  usr

[root@Test02 sysroot]# rm -rf linuxrc 

[root@Test02 sysroot]# for i in $(ls /);do [ -d /mnt/sysroot/$i ]|| mkdir /mnt/sysroot/$i ;done

1

2

3

[root@Test02 sysroot]# ls

bin   dev  home  lib64       media  mnt  opt   root  selinux  sys  usr

boot  etc  lib   lost+found  misc   net  proc  sbin  srv      tmp  var

       5.4)提供/mnt/sysroot/etc/inittab文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[root@Test02 sysroot]# cd etc

[root@Test02 etc]# ls

[root@Test02 etc]# touch inittab

[root@Test02 etc]# vim inittab

#使用init加載/etc/rc.d/rc.sysinit初始化系統

::sysinit:/etc/rc.d/rc.sysinit

#開啓3個虛擬控制檯,這是busybox的寫法,不要問why

tty1::askfirst:/bin/sh

tty2::askfirst:/bin/sh

tty3::askfirst:/bin/sh

#定義ctrl+alt+delete爲重啓系統快捷鍵

::ctrlaltdel:/sbin/reboot

#關機之前先卸載已掛載的文件系統

::shutdown:/bin/umount -a -r


        5.5)提供/mnt/sysroot/etc/rc.d/rc.sysinit文件用戶初始化系統

1

2

3

4

5

6

7

8

9

10

11

12

[root@Test02 sysroot]# cd etc

[root@Test02 etc]# mkdir rc.d

[root@Test02 etc]# touch rc.d/rc.sysinit

[root@Test02 etc]# chmod +x rc.d/rc.sysinit 

[root@Test02 etc]# vim rc.d/rc.sysinit

#!/bin/sh

echo -e "\t Welcome to \033[31;1mPriate Li Home\033[0m"

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -t devtmpfs none /dev

mount -n -o remount,rw /dev/sda2  /

/sbin/mdev -s


        5.6)修改/mnt/boot/grub/grub.conf文件

1

2

3

4

5

6

[root@Test02 etc]# vim /mnt/boot/grub/grub.conf 

timeout=3

default=0

title  PirateLi        

    root (hd0,0)        

    kernel /bzImage ro root=/dev/sda2 init=/sbin/init


        5.7)宿主機同步後掛起,啓動測試機

1

2

[root@Test02 etc]# sync

[root@Test02 etc]# sync

wKiom1VgZ8GDt5t4AAPZmHAOJLE096.jpg

            現在敲回車就可進入,使用命令poweroff進行關機

            5.8)啓動網絡,設定lo和eth0網卡地址和主機名

 使用poweroff命令關閉測試機,進入宿主機

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

[root@Test02 sysroot]# vim etc/rc.d/rc.sysinit

#!/bin/sh

echo -e "\t Welcome to \033[31;1mPriate Li Home\033[0m"

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -t devtmpfs none /dev

mount -n -o remount,rw /dev/sda2   /

/sbin/mdev -s

#設定ifconfig命令啓動lo 和eth0 網卡

/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 up

/sbin/ifconfig eth0 192.168.100.30 netmask 255.255.255.0 up

#設定主機名

[ -r /etc/sysconfig/network ]&&source /etc/sysconfig/network

[ -n $HOSTNAME ]&&/bin/hostname $HOSTNAME || /bin/hostname localhost


            5.9)編寫/mnt/sysroot/etc/sysconfig/network文件

1

2

3

[root@Test02 sysroot]# mkdir etc/sysconfig

[root@Test02 sysroot]# vim etc/sysconfig/network

HOSTNAME=Test64.lijun.com


            5.10)編寫/etc/fstab文件掛載文件系統

1

2

3

4

5

6

7

[root@Test02 sysroot]# vim etc/fstab

[root@Test02 sysroot]# vim etc/fstab

/dev/sda1       /boot   ext4    defaults 0 0 

/dev/sda2       /       ext4    defaults 0 0 

proc    /proc   proc    defaults 0 0 

sysfs   /sys    sysfs   defaults 0 0 

none    /dev/   devtmpfs        defaults 0 0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#在rc.sysinit腳本中添加mount -a 保證能根據/etc/fstab中設定掛載文件系統

[root@Test02 sysroot]# vim etc/rc.d/rc.sysinit 

#!/bin/sh

echo -e "\t Welcome to \033[31;1mPriate Li Home\033[0m"

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -t devtmpfs none /dev

mount -n -o remount,rw /dev/sda2   /

/sbin/mdev -s

/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 up

/sbin/ifconfig eth0 192.168.100.30 netmask 255.255.255.0 up

[ -r /etc/sysconfig/network ]&&source /etc/sysconfig/network

[ -n $HOSTNAME ]&&/bin/hostname $HOSTNAME || /bin/hostname localhost

mount -a


            5.11)同步並掛起宿主機,啓動測試機

wKioL1VgbrGg-GhQAANCYeIxX0U212.jpg


wKioL1VgbsGjs7pKAAEv5-v0LiQ875.jpg


            5.12)設定passwd,shadow,nsswitch文件,實現用戶認證登陸

1

2

3

4

5

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

[root@Test02 sysroot]# touch etc/passwd

[root@Test02 sysroot]# touch etc/shadow

[root@Test02 sysroot]# grep '^root\>' /etc/passwd > etc/passwd 

[root@Test02 sysroot]# grep '^root\>' /etc/shadow > etc/shadow

 

編譯dropbear

6.1)在宿主機上編譯dropbear

1

2

3

[root@Test02 source]# tar -xf dropbear-2015.67.tar.bz2 

[root@Test02 source]# cd dropbear-2015.67

[root@Test02 dropbear-2015.67]# ./configure && make && make install

    6.2)移植宿主機上的dropbear程序:dropbear dropbearkey dbclient 至測試機根文件分區磁盤

*複製腳本在第7項中提供

1

2

3

4

5

6

7

8

9

10

11

12

[root@Test02 sysroot]# bash /root/source/copy.sh 

Input a command(keyword 'quit' for outworld):>dropbear

copy /usr/local/sbin/dropbear ok

copy /usr/local/sbin/dropbear lib ok

Input a command(keyword 'quit' for outworld):>dropbearkey

copy /usr/local/bin/dropbearkey ok

copy /usr/local/bin/dropbearkey lib ok

Input a command(keyword 'quit' for outworld):>dbclient

copy /usr/local/bin/dbclient ok

copy /usr/local/bin/dbclient lib ok

Input a command(keyword 'quit' for outworld):>quit

[root@Test02 sysroot]#

    6.3)生成dropbear提供sshd服務需要的密鑰文件

1

2

3

4

[root@Test02 sysroot]# mkdir etc/dropbear

[root@Test02 sysroot]# dropbearkey -t dss -f /mnt/sysroot/etc/dropbear

[root@Test02 sysroot]# dropbearkey -t rsa -s 2048 -f /mnt/sysroot/etc/dropbear

[root@Test02 sysroot]#

    6.4)設定dropbear提供的sshd服務在開機後自啓動

1

2

3

4

5

[root@Test02 sysroot]# touch etc/rc.d/rc.local

[root@Test02 sysroot]# echo '/usr/local/sbin/dropbear -E'>etc/rc.d/rc.local 

[root@Test02 sysroot]# cat etc/rc.d/rc.local 

/usr/local/sbin/dropbear -E

[root@Test02 rc.d]# chmod +x rc.local

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[root@Test02 sysroot]# vim etc/rc.d/rc.sysinit

#!/bin/sh

echo -e "\t Welcome to \033[31;1mPriate Li Home\033[0m"

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -t devtmpfs none /dev

mount -n -o remount,rw /dev/sda2 /

/sbin/mdev -s

mkdir /dev/pts

/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 up

/sbin/ifconfig eth0 192.168.100.30 netmask 255.255.255.0 up

[ -r /etc/sysconfig/network ]&&source /etc/sysconfig/network

[ -n $HOSTNAME ]&&/bin/hostname $HOSTNAME || /bin/hostname localhost

mount -a

exec /etc/rc.d/rc.local


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