busybox制做initrd.img和根文件系统

(一)开发环境介绍

1.使用win7_64的笔记本安装Virtualbox虚拟机,笔记本cpu为i5-2450m。虚拟机上安装Ubuntu16.04系统做为编译环境,同时虚拟机也做为最小系统运行环境。

2.最小系统使用Linux内核版本选择4.15.0,内核配置使用x86_64默认配置(即便用命令make x86_64_defconfig)。busybox选择版本1.30.0,使用busybox制做initrd.img,而且同使用busybox制做根文件系统,busybox编译配置相同,只须要在默认配置上修改成静态连接(setting–Build static binary )。

3.在根目录新建文件夹/vita做为新系统启动分区,使用gparted分配10G(大小随便)给新分区,新分区设备文件为/dev/sda3。将新分区挂载在/vita目录,在此目录下新建/boot用于存放bzImage和initrd.img。同时/vita也存放根文件系统。制做好的目录以下:

web

(二)制做initrd.img

1.下载busybox包,解压,配置,编译,安装等步骤以后,会在当前目录下生产_install目录,里面有一些不依赖其余库的静态进程,能够直接运行。

咱们首先将_install拷贝到initramfs目录用于生成initrd.imgshell

mkdir initramfs

cp -R busybox-1.30.0/_install/* initramfs/

cd initramfs

2.测试initrd。因为内核将initrd.img镜像解压到根文件系统后就将运行权交于initrd.img中的/init程序,因此咱们能够自行选择是否要加载根文件系统,能够不加载根文件系统直接使用initrd.img里的内容作根文件系统,下面进行两种测试,单独运行initrd.img。

(1)测试一:使用linuxrc的内容做为启动脚本

① 因为咱们使用initramfs,因此内核运行时是找init文件而不是linuxrc,因此直接将linuxrc更名为initvim

mv linuxrc init

这里能够稍微解释下linuxrc的运行原理,在busybox的源码下/init/init.c有以下内容:

代表linuxrc的做用和init同样,也就是执行linuxrc就是执行/sbin/init。咱们知道busybox使用软连接将一个进程连接成多个进程,而后经过main函数args的第一个参数(也就是进程名)来区分具体执行哪个,咱们直接把文件名该为init其实就至关于执行了/sbin/init程序。

② 新建文件夹,添加配置文件bash

mkdir dev etc lib mnt proc sys

配置文件能够选择busybox里面的例子,在busybox-1.30.0\examples\bootfloppy\etc目录下,能够找到相关文件

将这些文件拷贝到initramfs/etc下,因而etc结构以下。

ide

cp -R ../busybox-1.30.0/examples/bootfloppy/etc/* etc/

之因此要添加配置文件是由于/init程序等同于/sbin/init,了解linux system V启动方式的同窗确定知道,/sbin/bin会根据/etc/inittab的配置内容进行相关配置,若是这里不进行配置运行内核时会首先提示找不到rcS文件,也即“can’t run ‘/etc/init.d/rcS’: No such file or directory”。

这里稍微解释下各个文件内容svg

etc/inittab函数

::sysinit:/etc/init.d/rcS

::respawn:-/bin/sh

tty2::askfirst:-/bin/sh

::ctrlaltdel:/bin/umount -a -r

简单说就是每一行表示一种执行策略,例如第一行表示在系统启动时执行RCS,第二行表示若是sh挂了会自动重启sh,第三行表示使用tty2启动的sh启动时会首先询问,第四行表示使用ctrl+alt+del快捷键时执行的程序。这里咱们改下配置内容学习

::sysinit:/etc/init.d/rcS

console::respawn:-/bin/sh

将sh启动的控制程序交给console,而且删除其余操做。测试

etc/fstab

proc/procprocdefaults 00

fstab表示系统启动时默认挂载的文件系统,一般能够把一些特殊文件系统挂载下,例如/proc,/sysfs

etc/profile

# /etc/profile: system-wide .profile file for the Bourne shells

echo

echo -n "Processing /etc/profile... "

# no-op

echo "Done"

echo

profile一般是使用tty并进行登陆时才会用到,profile是一般会调用~/.bashrc的配置修改用户环境变量。

etc/init.d/rcS

#! /bin/sh

/bin/mount -a

rcS在这里是做为inittab的启动脚本

③ 添加控制台设备文件

内核在准备好initramfs后会判断/dev/console是否存在,不存在就报错,存在就会继续执行/init并将之后的输出输出到控制台中。

mknod dev/console c 5 1

mknod dev/null c 1 3

这里我进行了删除测试,发现即便没有新建这两个设备结点也能正常运行,在查阅《深度探索Linux操做系统》后,发现里面有解答,除了咱们本身建立的initrd.img外,内核会本身建立一个内置的initramfs文件系统,并在内置initramfs中执行命令建立console设备结点。因此添加设备结点这一步咱们能够省略。

④ 配置grub,在/boot/grub.cfg中先新建菜单项,能够参考个人上一篇博客“Linux内核学习(3)最小系统制做”,再配置initrd的参数,表示initrd.img的位置,例如:

⑤ 生成initrd.img文件,并将此文件拷贝到/boot下,最后再重启

find . |cpio -o -H newc|gzip ../initrd3.img

cp ../initrd3.img /vita/boot

⑥ 在grub菜单中选择本身新建的菜单

启动后结果以下,执行下ls,发现只有initrd.img里面的内容,而不是根文件系统/vita下的内容

(2)测试二:自定义/init脚本

① 能够直接在上述基础上进行,也就是修改/init的内容。

rm init

vim init

init:

#!/bin/sh

#

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 "start /bin/sh"

exec /bin/sh

这里注意不能直接执行/bin/sh,须要先先挂载proc和sysfs,而后建立设备结点,不然会形成以下错误,表示init执行错误。mdev的做用是将sysfs文件系统下扫描的设备在/dev下建立设备结点。

② 修改init后的步骤和上述“测试一”同样,重启后显示以下

结果虽然执行了sh,可是仍有提示“can’t access tty”,并且部分busybox功能失效,例如执行reboot无任何反映,应该是未执行相关初始化的缘由。可是咱们这里只是测试,因此无需纠结。

3.使用initrd启动根文件系统

(1)当initrd中充当挂载根文件系统的桥梁时,这时initramfs/etc下能够不须要配置(这里咱们依旧保留,其实没有使用),而应当把配置文件移动到根文件系统中。

(2)修改initramfs/init启动脚本

vim init

init:

#!/bin/sh

#

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/sysroot..."

mount -t ext4 /dev/sda3 /mnt/sysroot

echo "Switch to read rootfs..."

exec switch_root /mnt/sysroot /sbin/init

这里咱们多执行了两步操做,挂载根文件系统/dev/sda3到/mnt/sysroot目录,执行switch_root切换根文件系统目录到/mnt/sysroot下,而且执行/sbin/init。

(三)制做根文件系统

1.制做根文件系统和initrd.img步骤相差无几,首先是同样的拷贝基本文件。

cp -R ../busybox-1.30.0/_install/* /vita

2.配置文件

cp -R etc/* /vita/etc/

3.建立相关文件,删除无用文件

cd /vita

mkdir -p dev etc lib mnt/sysroot proc sys

rm linuxrc

4.修改下fstab和rcS,使用fstab添加sysfs的挂载,使用rcS自动建立设备结点

vim etc/fstab

fstab:

proc/procprocdefaults 00

sysfs/syssysfsdefaults 0 0

修改rcS:

vim etc/init.d/rcS

rcS:

#!/bin/sh

/bin/mount -a

mdev -s

5.重启

能够看到log都正确的打印,输入ls后看到的目录的确是/vita目录,也就是正确切换到根文件系统了。

(四)常见错误

1.“Failed to create /dev/root:”,这种错误有时候会被误解为驱动问题,其实查看kernel源码会发现有以下调用顺序:

能够看到,若是init文件不存在(没指定参数时默认启动init),内核会主动挂载根文件系统,可是若是没有进行任何先前动做就去挂载通常都会失败,例如须要先进行挂载/proc和/sysfs。因此若是咱们忘记在initrd.img中写/init启动脚本会出现这种错误。

2.“can’t run ‘/etc/init.d/rcS’: No such file or directory”,这种错误比较常见,可是常常不那么容易弄懂。

我这里说一种我出现的问题,花了比较长的时间才解决。

首先个人根文件系统明明已经写了rcS并且也没有任何乱码,仔细检查根文件系统明明没有任何问题。这时我忽然想到,若是在initrd.img/init脚本中无心间执行了initrd.img中的/sin/init程序,那么此程序会检查有没有initrd.img/etc/inittab配置,若是没有此配置文件,会默认执行initrd.img/etc/init.d/rcS脚本,因此若是initrd.img/etc下什么文件都没有,那么首先报的问题就是缺乏initrd.img/etc/init.d/rcS。可是后来我仔细检查initrd.img/init内容发现并无执行到initrd.img/sbin/init。虽然没有解决问题,可是我却发现了另一个问题,initrd.img/init文件没有执行权限,也就是以下:

能够看到init文件的权限没有可执行权限,可是这个问题会影响到rcS吗,我又研究了一下kernel的源码,发现有以下片断:

if (ramdisk_execute_command) {

ret = run_init_process(ramdisk_execute_command);

if (!ret)

return 0;

pr_err("Failed to execute %s (error %d)\n",

ramdisk_execute_command, ret);

}

/*

* We try each of these until one succeeds.

*

* The Bourne shell can be used instead of init if we are

* trying to recover a really broken machine.

*/

if (execute_command) {

ret = run_init_process(execute_command);

if (!ret)

return 0;

panic("Requested init %s failed (error %d).",

execute_command, ret);

}

if (!try_to_run_init_process("/sbin/init") ||

!try_to_run_init_process("/etc/init") ||

!try_to_run_init_process("/bin/init") ||

!try_to_run_init_process("/bin/sh"))

return 0;

ramdisk_execute_command变量在默认状况下是/init,这段代码就是当/init执行不成功时会继续执行/sbin/init,而这时就会执行到上述initrd.img/sbin/init中,因此就会出现上述错误。

明白错误原理后只须要修改init权限,给全部用户添加执行:

chmod a+x init

从新重启后就正常了,这个问题其实不难解决,难的是报的问题很是奇怪不容易弄懂缘由。

学做Linux内核,Linux内核学习(3) 最小系统制做2 busybox制做initrd.img和根文件系统...相关推荐

  1. linux 制作box文件夹,用busybox制作自己简易的根文件系统

    当使用Busybox-1.2.0制作根文件系统 交叉编译器为3.3.2 make-3.8.1 STEP 1: 创建根文件系统目录,主要包括以下目录/bin,/etc,/dev,/mnt,/sbin,/ ...

  2. 51单片机基础知识学习 (最小系统板)

    什么是最小系统板?什么是开发板? 开发版是用来验证你的设计的板子,一般上面的东西很多,各式各样的,键盘,液晶屏,红外等等.(东西很多) 而最小系统板,就是说你实现这个系统需要的最少的设备,也就是除了你 ...

  3. ROS系统学习2---ROS最小系统的制作

    上一篇文章我们讲了ros的安装,并且运行了ros自带的一个简单程序. 下面,我们将从一个空的文件夹开始,一步步创建工作空间,包,和节点,并让该节点输出"Hello ros".

  4. 一文讲解Linux内核中根文件系统挂载流程

    根文件系统的概念 根文件系统是控制权从linux内核转移到用户空间的一个桥梁.linux内核就类似于一个黑匣子,只向用户提供各种功能的接口,但是功能的具体实现不可见,用户程序通过对这些功能接口的不同整 ...

  5. linux之mini2440内核移植

    与其它操作系统相比,Linux最大的特点:它是一款遵循GPL(General Public License  GNU通用公共许可证(简称为GPL),是由自由软件基金会发行的用于计算机软件的许可证.)的 ...

  6. linux 文件系统覆盖目录,Linux内核裁减及根文件系统定制

    一.内核编译 1.准备工作 (1)整理出系统需要支持的硬件.文件系统类型以及网络协议等内容. (2)建议用命令uname –r 查看一下系统的版本号,如果你的系统版本与将要编译的内核版本一致,建议将/ ...

  7. 基于S3C2410平台移植Linux 2.6内核指南

    安装交叉编译工具 Ø        下载交叉编译工具 (本文默认所有软件均下载在用户主目录下) arm-linux-gcc-3.4.1 -- 编译内核 URL: ftp://ftp.handhelds ...

  8. 【linux kernel】linux内核如何挂载根文件系统

    文章目录 一.前世今生 二.kernel_init线程入口 三.重磅角色-prepare_namespace 一.前世今生 在kernel_init线程函数中会调用kernel_init_freeab ...

  9. Linux学习笔记---使用BusyBox创建根文件系统(二)

    目录 向 rootfs 的"/lib "目录添加库文件 向 rootfs 的usr/lib 目录添加库文件 创建其他文件夹 根文件系统初步测试 向 rootfs 的"/l ...

最新文章

  1. 什么时候使用Java的@Override注释,为什么?
  2. Azure 怎么开通FTP
  3. 非常复杂,上双11数据大屏背后的秘密:大规模流式增量计算及应用
  4. 【less-6】sqli-labs靶场第六关(类似less-5)
  5. rhel6中dhcp服务器配置文件,如何在CentOS/RHEL 7/6/5配置DHCP服务器
  6. 【超详细】韦东山:史上最全嵌入式Linux学习路线图
  7. MeteoInfo介绍
  8. 字节跳动实习面试:三面无修改公开,看看他到底通过了吗?
  9. 第三十一篇 -- 学习第六十八天打卡20190911
  10. Cherno C++系列笔记20——P60~P61 为什么不使用using namespace std、命名空间
  11. linux无线网卡驱动编写,博通无线网卡驱动linux版
  12. J2SDK1.5-J2SDK5.0,哈哈
  13. 补点C#基础_022_json校验和json在线编辑器-bejson
  14. Arduino servo库函数说明(舵机函数库)
  15. fatal error C1189: #error : Building MFC application with /MD[d]
  16. 一位真正的科学思想家: 纪念人工智能之父Marvin Minsky教授
  17. Java 工厂设计模式
  18. 均值回归,逆市中的投资机会
  19. EventBus介绍与使用
  20. 计算机管理任务计划程序全部禁用,win10计划任务如何关闭_win10怎么禁用计划任务...

热门文章

  1. 【PYTHON,EXCEL】利用python进行EXCEL处理1 打开,读取数据的方法
  2. 使用css3属性做一个循环旋转的动画
  3. 2022-2028年中国中低温余热发电行业市场发展潜力及投资前景分析报告
  4. OpenStreetMap(OSM)历史数据下载
  5. FLTK学习-5-使用FLUID编程(3)
  6. 功能测试用例编写模板与教程
  7. 钻石型继承模型的内存分布
  8. Windows API-GDI入门基础知识详解(转)
  9. Nginx错误日志配置
  10. Unity中将图片改为支持透明背景模式