公司有个产品需要支持Reliance Nitro文件系统,方案中真正的根文件系统存在EMMC当中,需要做一个initramfs,当initramfs启动后再切换到EMMC当中的rootfs,以下是详细的initramfs制作过程,以及切换真实根文件系统需要注意的事项。
1.下载编译busybox
从busybox官网下载安装包,解压,进入解压后的目录下执行以下操作:
(1)进入配置界面
make menuconfig
(2)开启静态编译选项
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary(no shared libs)
(3)Corss Compile prefix 输入自己交叉编译器的前缀
(4)保存配置、退出,编译、安装
make
make install
(5)完成后可在当前目录的_install文件夹中看到如下内容
到此Busybox的工作已完成,接下来我们依赖以上生成的内容构建initramfs。
2.构建initramfs目录
(1)创建一个名为rootfs的目录,并将之前Busybox生成的_install目录下的内容全部拷入rootfs目录下
mkdir rootfs
sudo cp Busybox目录/_install/* rootfs/ -raf
(2)在rootfs目录下创建其他目录
mkdir dev etc lib usr var proc tmp home root mnt sys
(3)将Busybox中示例etc目录内容拷贝到rootfs的etc目录下
cp busybox目录/examples/bootfloppy/etc/* rootfs/etc -r
(4)修改profile内容如下
# /etc/profile: system-wide .profile file for the Bourne shells
PATH=/bin:/sbin:/usr/bin:/usr/sbin #可执行程序 环境变量
export LD_LIBRARY_PATH=/lib:/usr/lib #动态链接库 环境变量
/bin/hostname osee
USER="`id -un`"
LOGNAME=$USER
HOSTNAME='/bin/hostname'
PS1='[\u@\h \W]# ' #显示主机名、当前路径等信息:
(5)修改inittab内容如下
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
(6)修改fstab内容如下
proc /proc proc defaults 0 0
none /var ramfs defaults 0 0
none /sys sysfs default 0 0
none /dev/pts devpts default 0 0
tmpfs /dev/shm tmpfs defaults 0 0
(7)/dev目录中添加必要设备
mknod dev/console c 5 1
mknod dev/null c 1 3
以上一个简易的rootfs就制作完成,接下来将这个rootfs加入到Image中。
3.带initramfs的内核编译
(1)进入内核目录,进行内核配置
make menuconfig
General setup ------->
[*] Initial RAM filesystem and RAM disk(initramfs/initrd) support
[ 制作的rootfs路径] Initramfs source file(s)
(2)保存退出,编译内核 。
编译后的内核可以直接用U-boot引导进入,如图
系统起来第一个运行的程序是linuxrc。
4.切换到EMMC中的rootfs
(1)把上面制作的rootfs中的文件linuxrc重命名为init
mv linuxrc init
(2)重新创建一个linuxrc文件,内容如下
echo "exec initramfs init"
echo "mounting proc and sys"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
echo "detect and export hardware info"
mdev -s
echo "Mount real rootfs to /mnt/..."
mount -t ext4 /dev/mmcblk1p2 /mnt #挂载真正的文件系统
#echo "Switch to read rootfs..."
exec switch_root /mnt /sbin/init #切换到真正的文件系统
(3)给切换脚本加上权限
chmod +x linuxrc
(4)重新编译内核,即可切换到/dev/mmcblk1p2中的rootfs。
需注意的点:
1.switch_root命令必须是PID为1的进程运行才能生效,同时需在前加上exec;
2.制作的rootfs目录下需要有init文件才能正常切换根文件系统,这里我们将原来的linuxrc重命名为init,切换脚本作为linuxrc;
3.如果进入不了initramfs很大可能是交叉编译器有问题,编译内核的交叉编译器编译的Busybox不一定能运行,可多换几个交叉编译器或者Busybox版本试试。