手动创建一个小于10M的类嵌入式linux系统

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Field_Yang/article/details/50999813

前提:
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 SUBID=arch 
# cp arch/x86/boot/bzImage /mnt/boot 
# make manuconfig 

提示:为了实现后面的功能,请务必将文件系统中的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 --> Build Options --> Build Busybox as a static binary ( no share 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 /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/bash 
mount -t proc proc /proc
mount -t sysfs sysfs /sys 
mdev -s 
mount -t ext3 /dev/hda2 /mnt/sysroot
exec switch_root /mnt/sysroot /sbin/init 

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

4、制作initrd 
# find . | cpio --quit -H newc -c | 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 

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  \033[31mToyLinux\033[0m             "

echo -e "Remount the root filesystem ...........[  \033[32mOK\033[0m  ]"
mount -t proc proc /proc
mount -t sysfs sysfs /sys 
mount -o  remount,rw  /

echo -e "Creating the files of device ..........[  \033[32mOK\033[0m  ]"
mdev -s 

echo -e "Mounting the filesystem ...............[  \033[32mOK\033[0m  ]"
mount -a 
swapon -a 

echo -e "Starting the log daemon ...............[  \033[32mOK\033[0m  ]"
syslogd 
klogd

echo -e "Configuring loopback interface ........[  \033[32mOK\033[0m  ]"
ifconfig lo 127.0.0.1/24
ifconfig eth0 172.16.100.9/16 

#END 

而后让这个脚本具有执行权限: 
chmod +x etc/init.d/rc.sysinit 

4、配置init及其所需要的inittab文件

# cd /mnt/sysroot
# rm -f linuxrc 

添加如下内容: 
::sysinit:etc/init.d/rc.sysinit 
console::respawn:-/bin/sh 
::ctrlaltdel/sbin/reboot 
::shutdown:/bin/umount  -a -r 

5、为系统准备一个“文件系统表”配置文件/etc/fstab
# vim etc/fstab 

添加如下内容:
proc         /proc     proc    defaults    0 0 
sysfs        /sys      sysfs   defaults    0 0
/dev/hda2    /         ext3    defaults    1 1 
/dev/hda1    /boot     ext3    defaults    0 0  

6、由于在rc.sysinit文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示在控制台;
这将会经常性打断正在进行的工作,为了避免这种情况,我们这里为日志进程建立配置文件,为其指定将日志发送至/var/log/messages文件

# vim etc/syslog.conf 

添加如下一行:
*.info     /var/log/messages

六、至此一个简易的基于内存运行的小系统已经构建出来了,我们接下来为此系统创建所需的引导程序

grub-install --root-directory=/mnt  /dev/hda

说明:此处的/dev/hda 为目标系统所在的那块新磁盘:

接下来为grub建立配置文件:
# vim /mnt/boot/grub/grub.conf 

添加如下内容:

default=0 
timeout=5 
color light-green/back light-magenta/black 
title MageEdu Linux (2.6.38.5)
root (hd0,0)
kernel /bzImage ro root=/dev/hda2 quiet 
initrd /initrd.gz

接下来将为此块硬盘接入一个新的主机(这里使用虚拟机),启动一下并测试使用。

七、为新构建的ToyLinux启用虚拟控制台 

这个可以通过宿主机来实现,也可以直接启动刚构建成功的小linux进行配置,我们这里采用通过宿主机的方式(重新启动宿主机);
# cd /mnt/sysroot

将etc/inittab文件改为如下内容:

::sysinit:/etc/rc.d/rc.sysinit
tty1::askfirst:/bin/sh 
tty2::askfirst:/bin/sh 
tty3::askfirst:/bin/sh 
tty4::askfirst:/bin/sh 
tty5::askfirst:/bin/sh 
tty6::askfirst:/bin/sh 
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r 

好了,现在就可以测试验证六个虚拟机控制台的使用了。

八、尽管上述第七步已经实现了虚拟控制台,但其仍是直接进入系统,且系统没有用户账号等安全设施,这将不利于系统的安全性, 
因此,接下来的这步实现为系统添加用户账号(这里仍然基于宿主机实现)

1、为目标主机建立passwd账号文件
# cd /mnt/sysroot
# vim passwd 

添加如下内容:
root:x:0:0::/root:/bin/sh 
而后为root用户创建家目录
# mkdir root 

2、为目标主机建立group账号文件
# vim etc/group

添加如下内容:
root:x:0

3、为目标主机建立shadow影子口令文件,这里采用直接宿主机的shadow文件中关于root口令行的行来实现
# grep "^root" /etc/shadow> etc/shadow

注:等目标主机启动时,root用户的口令也是宿主机的root用户的口令,可以在目标主机启动以后在动手更改root用户的口令

4、将etc/inittab文件改为如下内容:

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

::respawn:/bin/sh 9600 tty1


------------马哥Linux学习笔记--------------
展开阅读全文

没有更多推荐了,返回首页