busybox制作ramdisk根文件系统

busybox制作ramdisk根文件系统

  • 如何制作一个根文件系统
  • 开启内核配置选项
  • busybox交叉编译
  • 制作根文件系统
    • 建立目录
    • 创建节点
    • etc目录添加配置相关配置文件
    • 增加文件权限、制作镜像
  • u-boot 修改启动参数,调试ramdisk.gz

如何制作一个根文件系统

制作一个根文件系统涉及到以下三块:

  • 内核要支持该类型的根文件系统
  • busybox制作根文件系统
  • u-boot启动参数设置

开启内核配置选项

本文的目的是制作一个ramdisk根文件系统,自然内核要支持该类型的文件系统,打开相关配置选项

cp arch/arm/configs/imx6ull_defconfig  .config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

1.支持initial RAM filesystem和RAM disk
busybox制作ramdisk根文件系统_第1张图片
2.支持RAM block,并设置RAM disk的数量和大小。这里设置的RAM disk的数量为8,内核启动后会在/dev下创建8个设备节点,实际在uboot中指定使用的是/dev/ram0,所以RAM disk的数量至少是1;设置的ramdisk是大小为8192K,如果这个大小和制作的的ramdisk不匹配,内核启动时会出现kernel panic,提示ramdisk格式不正确,挂载不上ramdisk,实际试验只要制作的ramdisk小于8192K就能正常启动。
busybox制作ramdisk根文件系统_第2张图片
3.支持ext2文件系统。ramdisk是一种内存虚拟磁盘技术,实质上并不是一种文件系统,它在内存上使用的是ext2类型格式。
busybox制作ramdisk根文件系统_第3张图片
重新编译内核,并把.config文件复制为imx6ull_defconfig保存

make zImage -j4 #生成的镜像为 arch/arm/boot/zImage
cp .config arch/arm/configs/imx6ull_defconfig

busybox交叉编译

1.从https://www.busybox.net/可以下载到busybox的源码

2.将busybox-1.32.1.tar.bz2放到编译服务器上解压,并配置busybox
进入目录,make menuconfig
busybox制作ramdisk根文件系统_第4张图片

  • Build static binary,使用的是静态链接的方式,可以免去拷贝大量的库文件
  • 指定cross compile prefix,即编译工具链,使用arm-linux-gnueabi-
  • 指定make install的目录,编译后busybox将安装在该目录

3.编译安装

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- #已设置cross compile prefix的话可直接make
make install

在安装目录下生成bin、linuxrc、sbin、usr,linuxrc即init进程,启动过程中由内核调用,bin和sbin目录下包含各种命令和工具,可以在配置busybox时选择是否开启某命令,其中linuxrc和各种命令工具都是指向bin/busybox的软链接。

制作根文件系统

建立目录

sudo mkdir fs_temp
cd fs_temp
sudo mkdir mnt tmp var sys proc etc lib dev root home
#将busybox编译成的bin、linuxrc、sbin、usr拷到该目录下
cp -R ../ramdsikfs/* ./

创建节点

cd dev
sudo mknod console c 5 1 		#创建控制台设备文件
sudo mknod null c 1 3 			#创建一个空的设备文件
sudo mknod ttymxc0 c 207 16 	#创建串口设备
#以上几个节点在内核执行init进程时要用到,所以要提前创建

etc目录添加配置相关配置文件

海思平台etc目录下存在如下文件,可根据功能需求添加,其中init.d/rcSinittabfstab是必须的。实际我是在imx6ull开发板上调试的,只创建了以上三个文件,给出的其他文件内容来自海思sdk,读者注意区分。
busybox制作ramdisk根文件系统_第5张图片

1.inittab配置文件

::sysinit:/etc/init.d/rcS
#getty要求设备启动输入login和passwd,配合group、passwd和shadow使用
#::respawn:/sbin/getty -L ttymxc0 115200 vt100 -n root -I "Auto login as root ..."
ttymxc0::askfirst:-/bin/sh #不需要输入login和passwd
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

:使用getty时会调用/bin/login,一定要创建group、passwd和shadw,我调试的时候没有创建这几个文件,无论输入什么都是Login incorrect

2.init.d目录

rcS脚本

#! /bin/sh

/bin/mount -a
#执行init.d目录下S[0-9][0-9]*脚本
#海思是执行以下几个脚本去创建节点,挂接devpts、tmpfs,使用udev和进行网络设置
#我自己操作时是手动创建节点的,是没有以下代码的
for initscript in /etc/init.d/S[0-9][0-9]*
do
	if [ -x $initscript ] ;
	then
		echo "[RCS]: $initscript"
		$initscript
	fi
done

S00devs脚本

#!/bin/sh
#创建节点
mknod /dev/console c 5 1
mknod /dev/ttyAMA0 c 204 64
mknod /dev/ttyS000 c 204 64
mknod /dev/null	   c 1 3

S01udev脚本

#!/bin/sh
#udev有关
mkdir /dev/pts
mount -t devpts devpts /dev/pts

mount -t tmpfs tmpfs /run

mkdir -p /dev/.udev
udevd --daemon
udevadm trigger
mdev -s

S80network脚本

#!/bin/sh
#设置网络参数
ipaddr=
bootp=
gateway=
netmask=
hostname=
netdev=
autoconf=

for ipinfo in `cat /proc/cmdline`
do
	case "$ipinfo" in
	ip=*)
		for var in  ipaddr bootp gateway netmask hostname netdev autoconf
		do
			eval read $var
		done << EOF
		`echo "$ipinfo" | sed "s/:/\n/g" | sed "s/^[ 	]*$/-/g"`
EOF
		ipaddr=`echo "$ipaddr" | cut -d = -f 2`
		[ x$ipaddr == x ] && ipaddr=x
		;;
	esac
done

[ -z "$ipaddr" ] && exit 0

echo "      IP: $ipaddr"
echo "   BOOTP: $bootp"
echo " GATEWAY: $gateway"
echo " NETMASK: $netmask"
echo "HOSTNAME: $hostname"
echo "  NETDEV: $netdev"
echo "AUTOCONF: $autoconf"

if [ x$ipaddr == x- ] ; then
	# use DHCP
	:
else
	cmd="ifconfig $netdev $ipaddr"
	[ x$netmask != x- ] && cmd="$cmd netmask $netmask"
	eval $cmd
	[ x$gateway != x- ] && route add default gw $gateway
fi

ifconfig lo 127.0.0.1

3.fstab文件:该文件被用来定义文件系统的"静态信息",这些信息被用来控制mount命令的行为,内容如下,表示执行rcS脚本中"mount -a"命令后要去挂载的文件系统。

#           
proc			/proc		proc	defaults,nodev,nosuid	0	0
sysfs			/sys		sysfs	defaults,nodev,nosuid	0	0
tmpfs			/dev		tmpfs	defaults				0	0
debugfs  /sys/kernel/debug  debugfs defaults  				0   0
tmpfs       	/tmp        tmpfs   mode=1777   			0   0

4.mstab文件:记载的是现在系统已经装载的文件系统,包括操作系统建立的虚拟文件等;而/etc/fstab是系统准备装载的。每当 mount 挂载分区、umount 卸载分区,都会动态更新 mtab,mtab 总是保持着当前系统中已挂载的分区信息,fdisk、df 这类程序,必须要读取 mstab 文件,才能获得当前系统中的分区挂载情况。当然我们自己还可以通过读取/proc/mount也可以来获取当前挂载信息 。

proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
devfs /dev devfs rw 0 0
devpts /dev/pts devpts rw 0 0

5.profile文件,环境变量相关,修改的内容是对所有用户起作用的

6.passwd和shadow文件,记录登录账户和密码

7.udev和mdev,用于自动创建节点,之后会另写一个文章介绍,本文以怎么制作根文件系统为主

增加文件权限、制作镜像

1.增加文件权限

cd temp_fs
sudo chown root -R *
sudo chgrp root -R *
sudo chmod 4755 bin/busybox

2.制作ramdisk镜像,并拷贝temp_fs的内容到里面

sudo dd if=/dev/zero of=ramdisk bs=1024 count=8192
sudo mke2fs -F -m0 ramdisk #格式化,-F强制,-m0不为管理员预留空间
sudo mount -t ext2 ramdisk /mnt/loop/
cd /mnt/loop/
sudo cp ~/work/temp_fs/* ./ -afR
cd -
sudo umount /mnt/loop/
gzip -v9 ramdisk   #生成ramdisk.gz

u-boot 修改启动参数,调试ramdisk.gz

修改u-boot的启动bootargs,我这边使用imx6ull开发板调试的

#将ramdisk.gz网络加载到0x83800000上
tftp 0x83800000 ramdisk.gz
#设置bootargs
setevn bootargs 'console=ttymxc0,115200 root=/dev/ram0 rw init=/linuxrc initrd=0x83800000,0x800000'
#启动
run bootcmd

下图是内核启动打印,成功进入文件系统。为什么mount root识别成的是ext4文件系统,具体还得看内核代码
在这里插入图片描述
至此,一个简单的ramdisk文件系统制作完毕,至于如何给文件系统添加想要的功能,等待下次用到的时候再更新吧~~

你可能感兴趣的:(根文件系统,linux)