Linux根文件系统的制作(转载)

2023-05-16

Linux根文件系统的制作


什么是文件系统

计算机的文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中。 
文件系统通常使用硬盘和光盘这样的存储设备,并维护文件在设备中的物理位置。但是,实际上文件系统也可能仅仅是一种访问数据的界面而已,实际的数据是通过网络协议(如NFS、SMB、9P等)提供的或者内存上,甚至可能根本没有对应的文件(如proc文件系统)。 
严格地说,文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。摘自<<维基百科>> 
磁盘需要首先分区,然后再在格式化成指定文件系统。Linux操作系统支持的文件系统有ext2,ext3,ext4,nfs,yaffs2等等,这些文件系统都可以在内核源代码中找到其定义和实现。 
这里写图片描述

什么是根文件系统

和Windows的C,D,E等盘符相似,Linux操作系统也可以将磁盘,Flash等存储设备划分为若干个区,在不同分区下存放不同类型的文件。比如Windows的C盘中就存放着启动系统所必须的一系列文件,而在Linux系统中,内核映像文件(在嵌入式系统众,内核一般单独存放在一个分区中),内核启动后运行的第一个程序(init),给用户提供操作界面的shell程序,应用程序所依赖的库等。这些必需的基本的文件集合就被称为根文件系统。它们都放在一个分区中,在系统启动后就会首先挂载这个分区,也就是挂载根文件系统。

为什么需要根文件系统

要回答这个问题,我们需要了解Linux操作系统的启动流程。Linux操作系统由三部分组成,分别是Bootloader,Linux kernel,File system.系统上电时首先执行的是Bootloader程序,主要做的任务是对硬件的初始化,并加载linux内核,linux内核启动后,就必须要挂载根文件系统,根文件系统的作用在上个小标题可以看到。没有文件系统的支持,即使linux内核运行起来了,我们也不能对内核进行操作。

如何制作根文件系统


准备阶段:需要用到的安装包有

Linux内核源代码包 
根文件系统需要用到的配置文件包 
用来移植根文件系统的常用命令的busybox安装包 
通过samba服务器将所有要用到的安装包都拷贝到虚拟机中 
我所使用的操作系统是红帽企业版6,也就是RHEL 6。

1.创建根文件系统与目录


1.1创建目录

mkdir /home/rootfs
cd /home/rootfs
mkdir bin dev sbin proc sys usr var tmp mnt etc
mkdir usr/bin usr/sbin usr/lib lib/modules

创建根目录下的各种子目录以及用户目录下的命令,库,模块等目录。

1.2创建设备文件

cd /home/rootfs/dev
mknod -m 666 console c 5 1
mknod -m 666 null c 1 3

在devices目录下创建两个必备的设备文件

1.3添加配置文件

将拷贝到linux下的配置文件安装包解压并讲解压后etc目录下的文件都复制到创建的根文件系统下的etc目录中

tar -xvzf etc.tar.gz
cp ./etc/* /home/rootfs/etc -rf 

1.4添加内核模块

进入解压后的linux源代码目录,执行第一条命令,指定架构和交叉编译工具链,编译生成的.ko文件就是我们需要用到的内核模块,但是它们是散落在linux内核代码目录下的各个子目录中的,所以需要执行第一条命令,将所有的内核模块都聚集起来并指定安装的目录,路径自然是要指定为我们所创建的根文件系统下了。这里指的根文件系统是所有文件和目录的集合。

cd /home/linux
make modules ARCH=arm CROSS_COMPILE=arm-linux-
make modules_install ARCH=arm INSTALL_MOD_PATH=/home/rootfs

1.5配置并编译busybox

所谓的制作根文件系统,就是创建各种目录,并且在里面创建各种文件。比如在/bin,/sbin目录下存放着各种可执行程序,在/etc目录下面存放配置文件,在/lib目录下面存放库文件。而busybox就是用来创建这些目录下的可执行文件,不包括配置文件和库文件。busybox为各种小型的或者嵌入式系统提供了一个比较完整的工具集。busybox是一个遵循GPL协议的开源项目,源代码可以在网上免费下载。

tar -xvzf /home/busybox1.13.3.tar.gz
cd /home/busybox1.13.3
make menuconfig
Build Options ---> [*]Build BusyBox as a static binary
(arm-linux-)Corss Compiler prefix
Installation Options ---> [*]Don't use /usr
(/home/rootfs)BusyBox installation prefix
make
make install

上面这段代码包括了解压以及通过图形界面来配置busybox。选择编译时静态链接库,交叉编译工具链的前缀,不安装到系统的/usr目录下,以及编译后安装到/home/rootfs,即我们制作的根文件系统下。退出后保存配置,然后就可以编译,安装了。安装完成后,可以在根文件系统比如/bin目录下看到很多可执行的文件。如果没有看到,那么请仔细检查在配置busybox时的指定路径名是否正确。到这里,整个根文件系统就制作好了。

2.挂载根文件系统到内核

2.1initramfs挂载

2.1.1搭建TFTP服务器

这里涉及到如何搭建TFTP服务器,以及如何通过TFTP服务器将制作好的内核映像下载到开发板。 
RHEL红帽操作系统安装软件方式有两种,一种是RPM机制,一种是yum机制。RPM安装软件不是很方便,因为可能安装完一个后还要后续再安装它的依赖,所以采用yum安装,yum可以自动安装软件需要的依赖,非常方便,Yum机制类似于Ubuntu的apt-get install。首先在仓库中找到tftp服务器软件,安装以后在根文件系统创建一个tftpboot目录,将开发板要下载的内核镜像文件放入其中,同时在tftp服务器的配置文件中指定链接的目录路径,以及将失能失效。最后重启服务器,这样tftp服务器就搭建完毕。

yum list|grep tftp
yum install tftp-server.i686
mkdir /tftpboot
chmod 777 /tftpboot
vim /etc/xinetd.d/tftp
disbale=no
server_args= -s /tftpboot

/etc/init.d/tftp restart

配置linux内核,选择使用initramfs方式来挂载文件系统。编译后将生成的uImage复制到创建/tftpboot目录下

cd /home/rootfs
ln -s ./bin/busybox init
cd /home/linux
make menuconfig ARCH=arm
General setup --->[*]Initial RAM filesystem and RAMdisk(initramfs/initrd) support
(/home/rootfs)Initramfs source file(s)
make uImage ARCH=arm CROSS_COMPILE=arm-linux-
cp /home/linux/arch/arm/boot/uImage /tftpboot

最后还需要设置一下开发板uboot的环境变量,设置加载内核后uboot传递给内核的启动参数。

printenv
setenv bootargs noinitrd console=ttySAC0,115200  
saveenv
tftp c0008000 uImage 
bootm c0008000

2.2NFS挂载

使用NFS来挂载的好处是显而易见的, 如果通过initramfs方式将文件系统挂载到内存,速度是很快,但是如果当你需要改动根文件系统下的文件或者目录时,你就需要每次都重新编译一次内核,编译内核是很慢的。 所以在开发阶段,使用NFS来挂载根文件系统,当需要改动时,通过网络实时生效,非常便捷省事。切换到Linux内核目录,启动图形配置界面,选择不使用initramfs方式来挂载文件系统,选择以NFS方式来挂载文件系统,保存退出后编译内核生成uImage镜像文件。

cd  /home/linux
make menuconfig ARCH=arm
General setup --->[]Initial RAM filesystem and RAMdisk(initramfs/initrd) support
File sysytem --->[*]Network filesystem--->[*]root filesystem on NFS
make uImage ARCH=arm CROSS_COMPILE=arm-linux-

设置开发板的启动参数 
1.root=/dev/nfs:并非真的设备,而是一个告诉内核经由网络取得根文件系统的旗标 
2.nfsroot 参数nfsroot这个参数告诉内核以哪一台机器,哪个目录以及哪个网络文件系统选项作为根文件系统使用,命令格式: nfsroot=[:]–指定网络文件系统服务端的互联网地址(IPaddress)。如果没有给定此栏位,则使用由nfsaddrs变量(见下面)所决定的值。此参数的用途之一是允许使用不同机器作为反向地址解析协议(RARP)及网络文件系统服务端。通常你可以不管它(设为空白)。 2)–服务端上要作为根挂入的目录名称。如果字串中有个‘%s’符记(token),此符记将代换为客户端互联网地址之ASCII表示法。 
3.nfsaddrs 命令格式nfsaddrs=:::::: 
1)–客户端的名称。如果空白,则使用客户端互联网地址之ASCII-标记法,或由启动协议接收的值;2)–要使用的网络设备名称。如果为空白,所有设备都会用来发出反向地址解析请求,启动协议请求由最先找到的设备发出。网络文件系统使用接收到反向地址解析协议或启动协议回应的设备。如果你只有一个设备那你可以不管它。 
3)–用以作为自动配置的方法。如果是rarp或是bootp则使用所指示的协议;如果此值为`both’或空白,若配置核心时有打开这两种协议则都使用;none表示不使用自动配置,这种情况下你必须指定前述栏位中所有必要的值。 此参数可以作为nfsaddrs的参数单独使用(前面没有任何字符),这种情况下会使用自动配置。然而,此种情况不能使用none作为值。

setenv bootargs noinitrd console=ttySAC0,115200 init=/init 
root=/dev/nfs rw nfsroot=192.168.199.115:/home/rootfs ip=192.168.199.120:192.168.199.115:192.168.199.1:255.255.255.0::eth0:off
saveenv

2.2.1搭建NFS服务器

想要让内核通过网络挂载文件系统,就需要搭建NFS服务器。NFS服务器软件的安装方式和上面的tftp服务器的方式一致,这里就不再赘述。

yum list | grep nfs
yum install nfs-utils

2.2.2启动NFS服务

NFS 依赖 rpcbind 服务,设置为其自动启动 
由于nfs服务依赖于rpc(远程过程调用)服务,所以在启动nfs服务之前,需要先启动rpc服务

chkconfig rpcbind on
service rpcbind start
service nfs start
tail /var/log/message
chkconfig nfs on

2.2.3配置NFS服务器

配置文件的意思是指定共享目录,也就是说我们将虚拟机中的根文件系统通过网络共享给开发板的linux内核使用。*代表所有IP都可以访问这个目录,权限包括可读可写,保存到磁盘等。配置完要重启NFS服务器生效。

vim /etc/exports
/home/rootfs *(rw,sync,no_root_squash)

/etc/init.d/nfs restart

下载内核后使用bootm命令启动内核,内核启动后便会通过网络来挂载根文件系统

tftp c0008000 uImage;bootm c0008000
  •  

最后附上整个过程的思维导图

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux根文件系统的制作(转载) 的相关文章

  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • 使用 sed 将 old-link-url 替换为 new-link-url

    我正在 bash 中编写一个脚本 将 old link url 替换为 new link url 我的问题是 sed 由于斜杠而无法替换 url 如果我只输入一些文字就可以了 my code sed e s old link new lin
  • Linux TCP服务器:在接受连接之前读取客户端的IP地址

    Related C Winsock API如何在接受连接之前获取连接客户端IP https stackoverflow com questions 716209 c winsock api how to get connecting cli
  • 静态链接共享对象?或者损坏的文件?

    我有一个从专有来源获得的库 我正在尝试链接它 但出现以下错误 libxxx so 文件无法识别 文件格式无法识别 Collect2 ld 返回 1 退出状态 确实 ldd libxxx so statically linked 这究竟意味着
  • 是否有可能通过 mmap 匿名内存“打孔”?

    考虑一个使用大量大致页面大小的内存区域 例如 64 kB 左右 的程序 每个内存区域的寿命都相当短暂 在我的特定情况下 这些是绿色线程的替代堆栈 如何最好地分配这些区域 以便一旦该区域不再使用 它 们的页面可以返回到内核 天真的解决方案显然
  • Linux 文本文件操作

    我有一个格式的文件 a href a href a href a href 我需要选择 之后但 之前的文本 并将其打印在行尾 添加后 例如 a href http www wowhead com search Su a a a a a
  • 使用脚本自动输入 SSH 密码

    我需要创建一个自动向 OpenSSH 输入密码的脚本ssh client 假设我需要通过 SSH 进入myname somehost用密码a1234b 我已经尝试过 bin myssh sh ssh myname somehost a123
  • linux下如何获取昨天和前天?

    我想在变量中获取 sysdate 1 和 sysdate 2 并回显它 我正在使用下面的查询 它将今天的日期作为输出 bin bash tm date Y d m echo tm 如何获取昨天和前天的日期 这是另一种方法 对于昨天来说 da
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • Bash 脚本 - 迭代 find 的输出

    我有一个 bash 脚本 其中需要迭代 find 命令输出的每一行 但似乎我正在迭代 find 命令中的每个单词 以空格分隔 到目前为止我的脚本看起来像这样 folders find maxdepth 1 type d for i in f
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • Scrapy FakeUserAgentError:获取浏览器时发生错误

    我使用 Scrapy FakeUserAgent 并在我的 Linux 服务器上不断收到此错误 Traceback most recent call last File usr local lib64 python2 7 site pack
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC

随机推荐

  • AXI STREAM ,AXIS总线的理解

    全兼容ZEDBOARD 开发板子 SYSCLK TAOBAO COM 1 xff0c VALID和READY 是所有AXI总线必须有的 xff0c VALID是MASTER告诉SLAVE数据已经展现在了总线上了 xff0c 你可以取走了 x
  • ZYNQ7 DACHE的重要操作

    Flush the SrcBuffer before the DMA transfer in case the Data Cache is enabled Xil DCacheFlushRange u32 TxPacket MAX PKT
  • OV7670摄像采集图像在VGA上显示的分析和实现,精确到每个时钟,每行代码。

    OV7670使用RGB565模式 xff0c 30FPS xff0c 采集分辨率为640X480 xff0c 保存在ZYNQ7芯片7Z020的内部BRAM VGA控制器在读出端读出数据 xff0c 并用12BIT的色彩深度现在VGA接口屏幕
  • Ubuntu 20.04 python2安装pip

    Ubuntu 20已经无法通过apt来安装python2的pip2了 xff0c 只能安装python3的pip 方法 先确保你有python2 暂时还是可以用apt安装python2 sudo apt install python2 下面
  • PetaLinux 2019.1详细安装步骤以及所需要文件

    这里主要根据UG1144文档 xff0c 这两天成功安装使用了PetaLinux的最新版本2019 1 一 xff0c 在虚拟机里安装Ubuntu16 04 1 xff0c 选Ubuntu 操作系统的版本是16 04 我最初尝试过18版本的
  • STC芯片在Keil中的添加与使用

    一 使用官方烧录工具 stc isp v6 88K exe在Keil中添加STC芯片 此烧录工具可在STC官网上下载 二 打开STC ISP软件 xff0c 选择右侧 Keil仿真设置 栏 三 选择 添加型号和头文件到Keil中 添加STC
  • boost 与 C++11 比较

    先不说boost的初始化表是多么怪异的形式了 c 43 43 11用大括号一括起来就OK了 auto 和 boost auto 差别太大了 xff0c 必须得告诉boost auto宏一个类型 xff0c 而非编译器本身的推断 xff0c
  • C++——struct和class的区别

    在C语言中struct是一种数据类型 xff0c 那么就肯定不能定义函数 xff0c 所以在面向c的过程中 xff0c struct不能包含任何函数 否则编译器会报错 而在C 43 43 中 xff0c 其特性也有了新发展 xff0c 就拿
  • roslaunch使用示例

    本文是看了学长ROS 的 roslaunch 中 xml 相关要点 文章之后做了小改动 xff0c 主要是对 roslaunch 文件的简单总结 需要完成的前序工作是已经创建了 catkin 工作空间 xff1b 创建了 catkin 程序
  • 四旋翼的运动原理及几个飞行问题

    四旋翼的运动及原理 飞行的问题 调试 四旋翼飞行器通过调节四个电机转速来改变旋翼转速 xff0c 实现升力的变化 xff0c 从而控制飞行器的姿态和位置 四旋翼飞行器是一种六自由度的垂直升降机 xff0c 但只有四个输入力 xff0c 同时
  • 以太网数据包长度限制

    我们使用以太网进行数据传输 xff08 UDP TCP xff09 xff0c 数据包的大小是有限制的 xff0c 并不是多长都可以 TCP IP协议从下到上包含 xff1a 链路层 IP层 传输层 应用层 链路层 xff1a 链路层的数据
  • 串口接收完整一帧数据包的3种方法

    本文介绍3种使用串口接受一帧完整数据包的方法 xff0c 串口接收数据是字节接收的 xff0c 串口每接收1字节数据 xff0c 产生一个串口中断 xff0c 我们在中断中将接收到的数据存放到buf中进行保存 xff0c 但是数据的发送和接
  • 补码原码转换

    本文主要讲述补码和原码之间的换算 1 原码 转 补码 xff1a 正整数的补码是它本身 xff0c 即 1的原码是0000 0001 xff0c 补码 还是 0000 0001 负整数的补码是符号位不变 xff0c 其余位按位取反 xff0
  • 有符号数与无符号数之间的转换

    本文讲解有符号数和无符号数之间的转换 针对同一数据类型有符号数和无符号数之间的转换 xff0c 例如 int 和 unsigned int 之间和 char 和 unsigned char 之间 这种情况下 xff0c 二者之间的数据类型长
  • Ubuntu由于修改etc/profile文件导致开机无法登陆问题解决办法(仅供参考)

    在安装jdk或者arm linux gcc等开发工具时需要修改profile xff0c 一不小心导致无法正常登录系统 xff0c 这时候可以试试用以下办法解决 xff1a 1 进入ubuntu登录页面 xff0c 按alt 43 ctrl
  • 一文看懂,用示波器查看串口UART的波形,什么是数据位、起始位、奇偶校验位

    先介绍一些概念 起始位 先发出一个逻辑 0 的 信号 xff0c 表示传输数据的开始 校验位 xff1a 数据位加上这一位后 xff0c 使得 1 的位数应为偶数 偶校验 或奇数 奇校验 xff0c 以此来校验数据传送的正确性 就比如传输
  • Could not get lock /var/lib/dpkg/lock 问题解决方法

    今天在ubuntu上安装sqlite 时 xff0c 执行命令sudo apt get y install sqlite3 时 xff0c 系统提示 xff1a Could not get lock var lib dpkg lock op
  • Linux 应用开发之系统调用

    系统调用 xff08 System Call xff09 是操作系统提供给用户程序调用的一组 特殊 函数接口 Linux 系统分为内核空间和用户空间 xff0c 用户空间只能通过系统调用接口与内核空间进行通信 Linux 系统提供了两种方式
  • Linux Qt 开发之多线程

    Qt 应用程序中所有的界面响应事件都在一个主线程中运行 xff0c 当我们去调用QApplication对象的exec 方法时 xff0c Qt就不断去循环查询当前的事件队列中有没有事件发生 xff0c 如果有则转去执行对应的槽函数 xff
  • Linux根文件系统的制作(转载)

    Linux根文件系统的制作 什么是文件系统 计算机的文件系统是一种存储和组织计算机数据的方法 xff0c 它使得对其访问和查找变得容易 xff0c 文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念 xff0