TinyEMU之文件系统构建


本文属于《 TinyEMU模拟器基础系列教程》之一,欢迎查看其它文章。

1 busybox简介

BusyBox作为一个集成了众多常用命令和工具的软件,用户可以直接通过命令行调用这些工具,无需单独安装每个工具。这使得BusyBox在嵌入式系统、小型Linux系统或资源受限的环境中特别有用,因为它可以显著减少系统所需的存储空间,同时提供基本的命令行操作和管理能力。

此外,BusyBox的集成性也提高了系统的可维护性和易用性。由于BusyBox包含了大量的常用命令,用户无需担心系统中缺少某些必要的工具,可以更加方便地进行系统配置、文件操作、网络管理等任务。

因此,编译好的BusyBox可执行程序,通常会被放到文件系统的/bin目录,可以使得这些命令和工具在系统启动时就被加载并可用,方便用户进行系统操作和管理。

2 编译busybox

busybox 官网:https://busybox.net/

可以通过 buildroot 或 busybox 来生成;busybox 代码量比较小,比较简单,生成的 rootfs 也比较小,因此采用busybox这种方式。

下载busybox源码

git clone https://gitee.com/mirrors/busyboxsource.git

此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/mirror/busybox

进入源码目录

cd busyboxsource

配置busybox

make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig

这里RISC-V交叉编译器安装,参考《TinyEMU之Linux Kernel编译》

选择使用静态编译

勾选Setting->---Buildroot Options->Build static binary

执行编译

make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j128

源码目录下,生成了二进制文件: busybox。
可以通过file busybox命令来查看编译成的busybox 是哪个平台的。

busybox中,包含了大量linux命令工具,当系统启动后,就可以很方便的使用这些命令;所以,我们后续,需要将busybox放入文件系统中。

3 创建文件系统目录结构

创建工作路径

cd ..
mkdir initramfs
cd initramfs/
sudo su				# 切换到 root 账户

创建文件系统主要目录

mkdir -p {bin,sbin,dev,etc,home,mnt,proc,sys,usr,tmp}
mkdir -p usr/{bin,sbin}
mkdir -p proc/sys/kernel

创建必要设备节点

cd dev/
sudo mknod sda b 8 0 
sudo mknod console c 5 1
cd ..

在dev目录下,创建一个名为sda的块设备文件节点,执行该命令后,dev/sda文件就被创建成功。

  • ”b”表示设备类型为块设备
  • 8表示主设备号
  • 0表示次设备号

在dev目录下,创建一个名为console的字符设备文件节点,执行该命令后,dev/console文件就被>创建成功。

  • ”c”表示设备类型为字符设备
  • 5表示主设备号
  • 1表示次设备号

拷贝编译好的 busybox

cp ../busyboxsource/busybox ./bin/

创建 init 文件

vim init

我们在initramfs目录下,创建init文件。
这个init文件,就是init进程,它是内核启动的第一个用户级进程。
我们把内核启动后,需要做的一些事情,写入init文件中,当内核启动后,就会自动执行它。

输入以下内容:

#!/bin/busybox sh
 
# Make symlinks
/bin/busybox --install -s

# Mount system
mount -t proc      proc      /proc
mount -t sysfs     sysfs     /sys
mount -t tmpfs     tmpfs     /tmp

# Busybox TTY fix
setsid cttyhack sh
 
# https://git.busybox.net/busybox/tree/docs/mdev.txt?h=1_32_stable
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
 
sh

接下来,解释这些命令。

  • /bin/busybox --install -s :将 BusyBox 中的多个命令链接到系统的 /bin目录中,作为单独的命令来使用。
  • mount -t proc proc /proc:把proc这个虚拟文件系统挂载到/proc目录,proc文件系统由内核提供。
  • mount -t sysfs sysfs /sys:把sysfs这个虚拟文件系统挂载到/sys目录,sysfs文件系统由内核提供。
  • mount -t tmpfs tmpfs /tmp:把tmpfs这个虚拟文件系统挂载到/tmp目录,tmpfs文件系统由内核提供。
  • setsid cttyhack sh:在后台启动一个新的终端shell会话进程,并将其与当前会话分离。
  • echo /sbin/mdev > /proc/sys/kernel/hotplug:设置Linux内核的热插拔处理脚本为/sbin/mdev,当系统中有设备被热插拔(例如,USB设备被插入或拔出)时,应该调用 /sbin/mdev 这个脚本来处理这些事件。
  • mdev -s:在系统启动或动态加载驱动程序时,扫描/sys/class和/sys/block目录,查找并读取dev属性文件,获取设备编号,然后根据这些信息在/dev目录下自动创建设备节点文件。

赋予 init文件 可执行权限

chmod +x init

到这里,initramfs目录下,已经具备了一个linux文件系统的基本目录了。

在这里插入图片描述

4 制作文件系统镜像

这一节,就是把上述目录结构,打包成ext2镜像文件。

4.1 创建 ext2 文件

生成4M大小的,空白镜像文件initramfs.ext2

dd if=/dev/zero of=initramfs.ext2 bs=1M count=4

将镜像文件initramfs.ext2,格式化为ext2文件系统

mkfs.ext2 initramfs.ext2

4.2 将目录结构拷贝进 ext2 文件

创建目录

mkdir /mnt/ext2/

将initramfs.ext2,挂载到/mnt/ext2/目录

mount -t ext2 initramfs.ext2 /mnt/ext2/

挂载到/mnt/ext2/目录后,当你在 /mnt/ext2/ 下写入文件或修改文件时,这些更改会反映到 initramfs.ext2 文件中。

拷贝initramfs目录内容,至/mnt/ext2/

cp -pr initramfs/* /mnt/ext2/

也就是,将目录结构拷贝进 initramfs.ext2 文件中了。

4.3 创建 init 链接

进入目录

cd /mnt/ext2/sbin/

在/mnt/ext2/sbin/目录下,创建init文件的软链接

ln -s ../init .

ln -s ../init .命令:在当前目录下创建一个名为init的符号链接,这个链接指向上一级目录中的init文件或目录。
相当于,linux可以从/和/sbin/目录下,执行init脚本。

4.4 取消挂载

cd -
umount /mnt/ext2/
sync		# 强制内容立刻写入文件

到这里,我们已经对initramfs.ext2文件写入完毕,写入的内容,主要包括busybox、目录结构、init文件以及软链接等。

initramfs.ext2,即为可供 TinyEMU 启动的 root 文件系统。

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值