天天看點

制作最小linux核心(1)

    ​​深入了解 Linux 2.6 的 initramfs 機制 (上)​​ 一文提到了制作簡易initramfs的過程;而另一篇文章​​使用udevadm(modinfo)查找linux下裝置對應的驅動​​ 則提到了比對裝置驅動的方法,本文對上面兩篇文章做個總結----定制一個最小系統。環境為:vmware10+ubuntu14.04(kernel 3.13.0)+Scsi虛拟磁盤。目标是用這個定制的核心引導系統,并往螢幕上輸出Hello initramfs。

1.首先需要定制的原料:linux核心源碼kernel 3.13.0和ubuntu做的patch更新檔:linux-lts-trusty_3.13.0-91.138~precise1.diff.gz。應用了更新檔以後,就開始定制之旅。既然寫了是定制,那必然需要移除不必要的核心子產品。是以,我們第一步就是運作make allnoconfig建立一個最小配置的核心,再這個基礎上一步步完善OS。

eugen@ubuntu:~$ cd Desktop/linux-3.13/
eugen@ubuntu:~/Desktop/linux-3.13$ make distclean
  ...
  CLEAN   .config .config.old .version include/generated/uapi/linux/version.h Module.symvers
eugen@ubuntu:~/Desktop/linux-3.13$ make allnoconfig
  ...
scripts/kconfig/conf --allnoconfig Kconfig
#
# configuration written to .config
#      

執行了上述指令後,核心除了選中必選項外,其餘都不選,夠幹淨的了~

2.現在開始根據正在運作的OS來定制核心,這步需要配置處理器型号,還需要配置PCI總線,畢竟虛拟機裡的裝置還是要挂載在PCI總線上的

2.1.确定CPU型号:

eugen@ubuntu:~/Desktop/linux-3.13$ cat /proc/cpuinfo |grep "model name"
model name  : Intel(R) Celeron(R) CPU        E3500  @ 2.70GHz #賽揚處理器 見笑了      

2.2配置核心支援的CPU型号,運作make menuconfig,依次選擇"Processor type and features"-"Processor family",我的CPU是賽揚,隻能選"Pentium-4/Celeron(P4-base)"項,大家按自己CPU的型号,選不同的選項。如果沒有與實際型号吻合的,可以選與它接近的一項:

2.1.1

制作最小linux核心(1)

2.1.2

制作最小linux核心(1)

2.1.3

制作最小linux核心(1)

由于我的虛拟機被配置為單核單處理器,是以核心不需要支援SMP

2.2開始配置裝置相關選項:

2.2.1.首先要啟用核心動态加載/解除安裝子產品的特性,依次勾選"Enable loadable module support"-"Module unloading":

制作最小linux核心(1)
制作最小linux核心(1)

2.3.開始配置磁盤驅動相關,這是最複雜的一步。定制錯了後,OS引導後會報panic

2.3.1.首先确定磁盤驅動器資訊,這需要用到/sys檔案系統/udevadm工具和modinfo工具:

eugen@ubuntu:~$ ls /sys/class/block/
sda2/  sr1/
sda/   sda5/  
sda1/  sr0/   #系統中隻有sda一塊磁盤
eugen@ubuntu:~$ udevadm info -a -p /sys/class/block/sda

  looking at device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0/block/sda':
    KERNEL=="sda"
    SUBSYSTEM=="block"
    ...

  looking at parent device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0/32:0:0:0':
    KERNELS=="32:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ...
  looking at parent device '/devices/pci0000:00/0000:00:10.0/host32/target32:0:0':
    KERNELS=="target32:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:10.0/host32':
    KERNELS=="host32"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:10.0':
    KERNELS=="0000:00:10.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="mptspi" #scsi磁盤驅動器用的子產品是mptspi
    ...

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00" #scsi磁盤挂載在PCI總線上
    SUBSYSTEMS==""
    DRIVERS==""      

根據以上資訊,定制這個最小系統需要PCI/mptspi/scsi等驅動,這就需要modinfo來檢視相應驅動資訊:

eugen@ubuntu:~$ lsmod
Module                  Size  Used by
mptspi                 22158  2 
mptscsih               38998  1 mptspi
ahci                   25579  0 
mptbase                95810  2 mptspi,mptscsih
libahci                27082  1 ahci      
eugen@ubuntu:~$ modinfo mptbase
filename:       /lib/modules/3.13.0-32-generic/kernel/drivers/message/fusion/mptbase.ko
version:        3.04.20
license:        GPL
description:    Fusion MPT base driver
...
eugen@ubuntu:~$ modinfo mptspi
filename:       /lib/modules/3.13.0-32-generic/kernel/drivers/message/fusion/mptspi.ko
version:        3.04.20
license:        GPL
description:    Fusion MPT SPI Host driver
...
eugen@ubuntu:~$ modinfo ahci
filename:       /lib/modules/3.13.0-32-generic/kernel/drivers/ata/ahci.ko
version:        3.0
license:        GPL
description:    AHCI SATA low-level driver
...      

2.3.2.配置PCI總線驅動,依次選"Bus Option"-"Pci support":

制作最小linux核心(1)
制作最小linux核心(1)

2.3.3.前面看到我的磁盤是Scsi類型,是以需要配置Scsi,依次選"Device Drivers"-"Scsi device support"--"Scsi device support","Scsi disk support"

制作最小linux核心(1)
制作最小linux核心(1)
制作最小linux核心(1)

2.3.4.Scsi磁盤需要Sata控制器,這一步比較關鍵,要從不同廠商的控制器驅動中挑選出合适的驅動。根據前面udevadm的輸出我的虛拟機,使用的是Fusion LSI磁盤驅動:依次選取1)"Device Driver"-"Serial ATA and Parallel ATA driver"-"AHCI SATA support";2)"Device Driver"-"Fusion MPT device support"-"Fusion MPT ScsiHost driver for SPI";

3)"Device Driver"-"Scsi device support"-"SCSI low-level drivers"-"LSI MPT Fusion SAS 2.0 Device Driver"

1).

制作最小linux核心(1)
制作最小linux核心(1)

2).

制作最小linux核心(1)
制作最小linux核心(1)

3).

制作最小linux核心(1)
制作最小linux核心(1)

3.裝置驅動配置完畢,需要再配置核心支援的檔案系統和ELF檔案格式,同時配置核心支援initramfs

3.1.選取"File Systems"-"The Extend 4(ext4) filesystem"

3.2.選取"Executable file formats"-"kernel support for ELF binaries"

3.3.選取"General setup"-"Initial Ram filesystem and Ram disk"

制作最小linux核心(1)

完成這些以後,就可以編譯核心并拷貝bzImage到/boot目錄下:make all -j4&& sudo cp arch/x86/boot/bzImage /boot

4.制作initramfs.

上面的步驟僅僅完成了核心部分的制作,這還是不夠的:我們還差個根檔案系統。是以現在開始制作根檔案系統。

先靜态編譯init.c用于往螢幕上輸出Hello World!

$ cd initramfs
$ cat init.c
#include <stdio.h>
int main()
{
  printf("Hello World!\n");
  sleep(99999);
  return 0;
}
$ gcc -static -o init init.c
$ mkdir -p dev
$ sudo mknod dev/console c 5 1      

恩,printf輸出的目标是螢幕,是以我們還需要一個console裝置節點,這個可以用mknod生成。最後是将initramfs/目錄下的檔案打包:

$find .|cpio -o -H newc|gzip -3 > ../initrd.img
$sudo cp ../initrd.img /boot      

5.制作啟動引導項,這個隻要将/boot/grub/grub.cfg中的引導項複制一份照着修改即可:

制作最小linux核心(1)

6.重新開機系統,選擇grub中設定的引導項,最終在螢幕上輸出"Hello World":

制作最小linux核心(1)

繼續閱讀