一步步手动构建小于10M的类嵌入式Linux系统

2019-07-12 15:39发布

前提:
1、一个作为宿主机的Linux;本文使用的是Redhat Enterprise Linux 5.8;
2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,为了降低复杂度,这里添加使用一块IDE接口的新硬盘;
3、Linux内核源码,busybox源码;本文使用的是目前最新版的linux-2.6.38.5和busybox-1.20.2。


说明:本文是一个step by step的实做指南;


一、为系统上的新硬盘建立分区,这里根据需要先建立一个大小为100M的主分区作为新建系统的boot分区和一个512M的分区作为目标系统(即正在构建的新系统,后面将沿用此名称)的根分区;100M的分区格式化后将其挂载至/mnt/boot目录下;512M的分区格式化后将挂载至/mnt/sysroot目录;


说明:
1、此处的boot和sysroot的挂载点目录名称尽量不要修改,尤其是boot目录,否则您必须保证后面的许多步骤都做了相应的改动;
2、新建系统的boot目录也可以跟根目录在同一个分区,这种方式比独立分区还要简单些,因此这里将不对此种方法再做出说明;


二、编译内核源代码,为新系统提供一个所需的内核(本例中的源代码包都位于/usr/src目录中)


# cd  /usr/src
# tar jxvf linux-2.6.38.5.tar.bz2
# ln  -sv  linux-2.6.38.5  linux
# cd linux


然后下载ftp://172.16.0.1/pub/Sources/kernel/kernel-2.6.38.1-i686.cfg至当前目录中,并重命名为.config。


# make menuconfig


根据您的实际和规划选择所需要的功能;本实例计划制作一个具有网络的功能的微型linux且不打算使用内核模块,因此,这里选择把本机对应的网卡驱动直接编译进了内核。作者使用的是vmware Workstation虚拟机,所以,所需的网上驱动是pcnet32的,其它的均可按需要进行选择。选择完成后需要保存至当前目录下.config文件中。


# make  SUBDIR=arch/
# cp arch/x86/boot/bzImage  /mnt/boot


# make menuconfig


提示:为了实现后面的功能,请务必将文件系统中的ext3和网卡的驱动程序直接编译进内核;否则,就需要手动装载这些相关文件系统的模块;


三、编译busybox


# cd /usr/src
# tar  -jxvf  busybox-1.20.2.tar.bz2
# cd  busybox-1.20.2
# mkdir include/mtd 
# cp  /usr/src/linux/include/mtd/ubi-user.h  include/mtd/
# make menuconfig


说明:
1、此处需要选择 Busybox Settings --> Build Options -->  Build BusyBox as a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库的静态二进制文件,从而避免了对宿主机的共享库产生依赖;但你也可以不选择此项,而完成编译后把其依赖的共享库复制至目标系统上的/lib目录中即可;这里采用后一种办法。
2、修改安装位置为/mnt/sysroot;方法为:Busybox Settings --> Installation Options --> (./_install) BusyBox installation prefix,修改其值为/mnt/sysroot。


# make  install


安装后的文件均位于/mnt/sysroot目录中;但为了创建initrd,并实现让其启动以后将真正的文件系统切换至目标系统分区上的rootfs,您还需要复制一份刚安装在/mnt/sysroot下的busybox至另一个目录,以实现与真正的根文件系统分开制作。我们这里选择使用/mnt/temp目录;


# mkdir -pv /tmp/busybox
# cp -r /mnt/sysroot/*  /tmp/busybox


四、制作initrd


# cd  /tmp/busybox


1、建立rootfs:
# mkdir -pv  proc  sys  etc/init.d  tmp  dev  mnt/sysroot


2、创建两个必要的设备文件:
# mknod  dev/console  c  5  1
# mknod  dev/null  c  1  3


3、为initrd制作init程序,此程序的主要任务是实现rootfs的切换,因此,可以以脚本的方式来实现它:


# rm  linuxrc
# vim  init
添加如下内容:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
insmod /lib/modules/jbd.ko
insmod /lib/modules/ext3.ko
mdev -s
mount -t ext3 /dev/hda2  /mnt/sysroot
exec  switch_root  /mnt/sysroot  /sbin/init


给此脚本执行权限:
chmod  +x  init


4、制作initrd
# find  .  | cpio  --quiet  -H newc  -o  | gzip  -9 -n > /mnt/boot/initrd.gz


五、建立真正的根文件系统


# cd  /mnt/sysroot


1、建立rootfs:
# mkdir -pv  proc  sys  etc/rc.d/init.d  tmp  dev/pts  boot  var/log  usr/lib


2、创建两个必要的设备文件:
# mknod  dev/console  c  5  1
# mknod  dev/null  c  1  3


3、建立系统初始化脚本文件


# vim  etc/rc.d/rc.sysinit


添加如下内容:
  
#!/bin/sh
echo -e " Welcome to