移植Linux:如何制作rootfs?

news2024/9/21 15:03:27

一、分析

1. 文件系统简介

       理论上说一个嵌入式设备如果内核能够运行起来,且不需要运行用户进程的话,是不需要文件系统的,文件系统简单的说就是一种目录结构,由于 linux操作系统的设备在系统中是以文件的形式存在,将这些文件进行分类管理以及提供和内核交互的接口,就形成一定的目录结构也就是文件系统,文件系统是为用户反映系统的一种形式,为用户提供一个检测控制系统的接口。

根文件系统,我认为根文件系统就是一种特殊的文件系统,那么根文件系统和普通的文件系统有什么区别呢?

       由于根文件系统是内核启动时挂在的第一个文件系统,那么根文件系统就要包括Linux启动时所必须的目录和关键性的文件;

     例如Linux启动时都需要有init目录下的相关文件,在 Linux挂载分区时Linux一定会找/etc/fstab这个挂载文件等,根文件系统中还包括了许多的应用程序bin目录等,任何包括这些Linux 系统启动所必须的文件都可以成为根文件系统。

     Linux支持多种文件系统,包括ext2、ext3、vfat、ntfs、iso9660、jffs、yaffs、romfs和nfs等,为了对各类文件系统进行统一管理,Linux引入了虚拟文件系统VFS(Virtual File System),为各类文件系统提供一个统一的操作界面和应用编程接口。

    Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件系统,则系统会出错而退出启动。之后可以自动或手动挂载其他的文件系统。因此,一个系统中可以同时存在不同的文件系统。

   不同的文件系统类型有不同的特点,因而根据存储设备的硬件特性、系统需求等有不同的应用场合。在嵌入式Linux应用中,主要的存储设备为 RAM(DRAM, SDRAM)和ROM(常采用FLASH存储器),常用的基于存储设备的文件系统类型包括:jffs2, yaffs, cramfs, romfs,ramdisk, ramfs/tmpfs等。

2.    基于FLASH的文件系统

2.1 Cramfs:Compressed ROM File System

    •它的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性。由于以上特性,Cramfs在嵌入式系统中应用广泛。

    但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容对进行扩充。Cramfs映像通常是放在Flash中。

2.2 jffs2

   •Jffs2: 日志闪存文件系统版本2 (Journalling Flash FileSystem v2)

   •主要用于NOR型闪存,基于MTD驱动层,特点是:可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等。

  •缺点主要是当文件系统已满或接近满时,因为垃圾收集的关系而使jffs2的运行速度大大放慢。jffs不适合用于NAND闪存主要是因为NAND闪存的容量一般较大,这样导致jffs为维护日志节点所占用的内存空间迅速增大,另外,jffs 文件系统在挂载时需要扫描整个FLASH的内容,以找出所有的日志节点,建立文件结构,对于大容量的NAND闪存会耗费大量时间。

2.3.yaffs:Yet Another Flash File System

   •yaffs/yaffs2是专为嵌入式系统使用NAND型闪存而设计的一种日志型文件系统。与jffs2相比,它减少了一些功能(例如不支持数据压缩),所以速度更快,挂载时间很短,对内存的占用较小。另外,它还是跨平台的文件系统,除了Linux和eCos,还支持WinCE, pSOS和ThreadX等。yaffs/yaffs2自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD与 VFS,直接对文件系统操作。当然,yaffs也可与MTD驱动程序配合使用。

   •yaffs与yaffs2的主要区别在于,前者仅支持小页(512 Bytes) NAND闪存,后者则可支持大页(2KB) NAND闪存。同时,yaffs2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。

2.4. 网络文件系统NFS (Network File System)

    NFS是由Sun开发并发展起来的一项在不同机器、不同操作系统之间通过网络共享文件的技术。

在嵌入式Linux系统的开发调试阶段,可以利用该技术在主机上建立基于NFS的根文件系统,挂载到嵌入式设备,可以很方便地修改根文件系统的内容。

所采用的工具:mkfs.cramfs,mkfs.jffs2,mkfs.yaffs

http://sourceforge.net/projects/cramfs/
http://sourceforge.net/projects/jffs2os/
http://sourceforge.net/projects/yaffs/

二、根文件系统的组成

1. 根文件系统目录内容简介

  • bin  :基本的可执行文件

  • opt  :添加的软件包

  • boot :启动时需要的一些文件

  • proc :内核及进程信息的虚拟文件系统

  • dev : 设备文件

  • root:root用户目录

  • etc: 系统配置文件

  • sbin:系统管理的程序

  • home : 用户目录

  • tmp : 临时文件

  • lib : 库文件

  • usr : 应用程序

  • mnt : 挂载文件系统的挂载点

  • var : 存放系统日志或一些服务程序的临时文件

2. 嵌入式环境需要移植的目录

根文件系统中的每一个顶级目录都有特定的用途和目的 ,但并不是所有的目录在嵌入式环境下都需要,我们只创建需要的一些目录:

 /bin /sbin  /etc /proc  /tmp  /var /dev  /mnt

Linux根文件系统至少应包括以下几项内容。

  1. 基本的文件系统结构,包含一些必需的目录比如:/dev,/proc,/bin,/etc,/lib,/usr,/tmp等。

  2. 基本程序运行所需的库函数,如glibc。

  3. 基本的系统配置文件,比如rc.sysinit,inittab等脚本文件。

  4. 必要的设备文件支持:/dev/hd*,/dev/tty*,/dev/fd0。

  5. 基本的应用程序,如sh,ls,cp,mv等。

3. 移植需要做的工作

  1. 把全局配置文件放入/etc目录下。

  2. 将设备文件信息放入/dev目录下,设备名可以作为符号链接定位在/dev中或/dev子目录中的其他设备存在。

  3. 操作系统核心定位在/或/boot,若操作系统核心不是作为文件系统的一个文件存在,不应用它。

  4. 库存放的目录是/lib。

  5. 存放系统编译后的可执行文件、命令的目录是/bin,/sbin,/usr。

三、 默认预置条件

1) 交叉编译工具

需要预先安装好交叉编译器 ,一口君安装版本是:arm-none-linux-gnueabi-gcc 默认在ubuntu中安装目录是:

/home/peng/toolchain/gcc-4.6.4/
2) tftp服务器

开发板下载内核镜像和设备树需要借助tftp服务器,配置信息如下:

peng@ubuntu:~$ cat /etc/default/tftpd-hpa 
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"

服务器根目录是**/tftpboot**

3) nfs服务器

内核启动后挂载文件系统需要通过nfs服务器,nfs服务器设置如下:

peng@ubuntu:~$ cat /etc/exports 
# /etc/exports: the access control list for filesystems which may be exported
#  to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/source/rootfs *(rw,sync,no_subtree_check)

四、文件系统制作步骤

1、 源码下载

我们选择的版本是busybox-1.22.1.tar.bz2下载路径为:

http://busybox.net/downloads/

2、 解压源码

$ tar  xvf  busybox-1.22.1.tar.bz2

3、 进入源码目录

$ cd  busybox-1.22.1

4、 配置源码

选择制作静态库,并设置交互编译工具链的前缀arm-none-linux-gnueabi-如果是其他工具链,按照例子填写即可。

$ make menuconfig
Busybox Settings ---> 
  Build Options --->
   [*] Build BusyBox as a static binary (no shared libs)
   [ ] Force NOMMU build
   [ ] Build with Large File Support (for accessing files > 2 GB)
   (arm-none-linux-gnueabi-) Cross Compiler prefix
   () Additional CFLAGS

5、 编译

$ make

6、 安装

busybox默认安装路径为源码目录下的_install

$ make  install 

7、 进入安装目录下

默认创建以下4个文件或者文件夹

$ cd  _install
$ ls
bin  linuxrc  sbin  usr

8、 创建其他需要的目录

$ mkdir  dev  etc  mnt  proc  var  tmp  sys  root 

9、 添加库

我们安装的交叉工具链中有我们所需要的可以在开发板上使用的库, 将其拷贝到_install目录下即可:

$ cp  /home/linux/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/  .  -a

修改文件权限并删除静态库和共享库文件中的符号表

$chmod  +w  lib
$chmod  +w  lib/*
$ rm  lib/*.a
$ arm-none-linux-gnueabi-strip  lib/*

删除不需要的库,确保所有库大小不超过8M

$ du  -mh   lib/

10、 添加系统启动文件

在etc下添加文件inittab,文件内容如下:

#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# stuff to do when restarting the init process
::restart:/sbin/init
# stuff to do before rebooting
::ctrlaltdel:/sbin/reboot

在etc下添加文件fstab,文件内容如下:

#device     mount-point   type      options         dump     fsck order
proc       /proc         proc      defaults       0       0
tmpfs      /tmp         tmpfs     defaults          0           0
sysfs      /sys          sysfs     defaults         0           0
tmpfs      /dev         tmpfs     defaults          0           0

【注意】这里我们挂载的文件系统有三个proc、sysfs和tmpfs。在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要确保内核有tmpfs的支持。

修改内核配置:

$ make menuconfig
File systems --->
  Pseudo filesystems ---> 
   [*] Virtual memory file system support (former shm fs)
   [*] Tmpfs POSIX Access Control Lists

重新编译内核

在etc下创建init.d目录,并在init.d下创建rcS文件,rcS文件内容为:

#!/bin/sh
# This is the first script called by init process
/bin/mount  -a  挂载fstab制定的所有文件系统
echo  /sbin/mdev  >  /proc/sys/kernel/hotplug
/sbin/mdev  -s

为rcS添加可执行权限:

$ chmod   +x  init.d/rcS

在etc下添加profile文件,文件内容为:

#!/bin/sh
export HOSTNAME=farsight
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH  LD_LIBRARY_PATH
mknod dev/console c  5  1    该文件节点是必须的

重要:新制作的文件系统尺寸若超出8M,删除不需要的库文件,比如c++库等。

11. 测试

制作完毕的根文件系统可以让开发板启动后通过nfs挂载到ubuntu中,

     1、删除原先的/source/rootfs

$ sudo  rm  -rf  /source/rootfs 

    2、将我们新建的根文件系统拷贝到/source/rootfs目录下

$sudo  mkdir  /source/rootfs
$ sudo  cp  _install/*   /source/rootfs   –a

 

    3、设置uboot环境变量

# setenv serverip 192.168.9.120
# setenv ipaddr 192.168.9.233
# setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000  –  42000000
#setenv bootargs root=/dev/nfs nfsroot=192.168.9.120:/source/rootfs rw console=ttySAC2,115200  init=/linuxrc  ip=192.168.9.233
# saveenv

重新启动开发板,查看是否能够正常挂载,功能是否正常

图片

五、制作ramdisk文件系统

通过NFS测试以后,就可以制作ramdisk文件系统了,具体如下:

1、制作一个大小为8M的镜像文件

 $ cd  ~
$ dd  if=/dev/zero  of=ramdisk  bs=1k  count=8192 (ramdsik为8M)
 If: input file
 Of: output file

2、格式化这个镜像文件为ext2

$ mkfs.ext2  -F  ramdisk

3、在mount下面创建initrd目录作为挂载点

$ sudo  mkdir  /mnt/initrd

4、将这个磁盘镜像文件挂载到/mnt/initrd下

注意这里的ramdisk不能存放在rootfs目录中

$ sudo  mount  -t  ext2   ramdisk  /mnt/initrd

5、将测试好的文件系统里的内容全部拷贝到 /mnt/initrd目录下面

$ sudo  cp  /source/rootfs/*   /mnt/initrd  –a

如果拷贝遇到错误,需要再次删除不需要的库,比如c++库

6、卸载/mnt/initrd

$ sudo  umount  /mnt/initrd

7、压缩ramdisk为ramdisk.gz

$ gzip  --best  -c  ramdisk  >  ramdisk.gz

8、格式化为uboot识别的格式并拷贝到/tftpboot下

$ mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip  -d ramdisk.gz  ramdisk.img
$ cp  ramdisk.img  /tftpboot

9、配置内核支持RAMDISK

制作完 initrd.img.gz后,需要配置内核支持RAMDISK作为启动文件系统

make menuconfig
File systems  --->
  <*> Second extended fs support
Device Drivers
  SCSI device support  --->
   <*> SCSI disk support
  Block devices  --->
   <*>RAM  block  device  support   
   (16)Default number of RAM disks  
   (8192) Default RAM disk size (kbytes)   (修改为8M) 
General setup  --->
  [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

重新编译内核,复制到/tftpboot

10、在U-BOOT命令行重新设置启动参数:

# setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;tftp 43000000  ramdisk.img\;bootm 41000000 43000000 42000000
# saveenv

重新启动开发板查看能否正常启动

【注意】 因为各个开发板命令会有所差异,uboot命令的设置要厂家出厂的手册操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2152636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cypress安装与启动(开始学习记录)

一 Cypress安装 使用npm安装 1.查看node.js npm的版本&#xff0c;输入 npm --version 和 node --version&#xff0c;node.js没安装的可以去中文网下载最新稳定版安装&#xff0c;npm不建议升级到最新版本&#xff0c;会导致安装Cypress时Error: Cannot find module ansi-st…

2-94 基于matlab的最佳维纳滤波器的盲解卷积算法

基于matlab的最佳维纳滤波器的盲解卷积算法。维纳滤波将地震子波转换为任意所需要的形态。维纳滤波不同于反滤波&#xff0c;它是在最小平方的意义上为最 佳。基于最佳纳滤波理论的滤波器算法是莱文逊(Wiener—Levinson)算法。程序提供了4种子波和4种期望输出&#xff1a;零延迟…

JavaEE: 深入探索TCP网络编程的奇妙世界(一)

文章目录 TCPTCP协议段落格式TCP相关机制TCP核心机制一: 确认应答32位序号32位确认序号后发先至问题 TCP TCP要比UDP更复杂一些~ TCP的全称为"传输控制协议".他负责对数据的传输进行一个详细的控制. TCP协议段落格式 源/目的端口号: 表示数据是从哪个进程来.到哪个…

Innodb内存结构

缓冲池Buffer Pool: 缓冲池是innodb内存结构缓冲区中的核心部分&#xff0c;在服务启动的时候服务器会向操作系统申请一块大小为128MB的内存空间&#xff0c;所有对数据库中数据的增删查改操作均在缓冲池bufferPool中完成&#xff0c;并且缓冲区中其他组件的描述信息也都存储在…

[Linux]Vi和Vim编辑器

Vi和Vim编辑器 Linux系统会内置vi文本编辑器, 类似于windows中的记事本 Vim具有程序编辑的能力, 可以看作是Vi的增强版本, 可以进行语法检查, 代码补全,代码编译和错误调整等功能 Vi和Vim的模式 快速入门 使用vim开发一个Hello.java程序 通过Xshell连接Linux系统命令行输入…

技术美术百人计划 | 《4.5 DOF景深算法》笔记

1. 景深定义 景深&#xff08;Depth of Field&#xff0c;DOF&#xff09;&#xff0c;是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。镜头光圈、镜头焦距、及焦平面到拍摄物的距离是影响景深的重要因素。在聚焦完成后&#xff0c;焦点…

2024年Q3国际信息系统安全认证联盟(ISC2)内部研讨会要点分享

2024年是CISSP认证成立30周年&#xff0c;这是一项具有里程碑意义的成就&#xff0c;代表了CISSP在网络安全领域的卓越、创新和领导力。博主于今年9月份参加了ISC2&#xff08;国际信息系统安全认证联盟&#xff09;组织的2024年第3季度内部网络研讨会&#xff0c;针对会议中的…

【sgCreateCallAPIFunction】自定义小工具:敏捷开发→调用接口方法代码生成工具

<template><div :class"$options.name" class"sgDevTool"><sgHead /><div class"sg-container"><div class"sg-start"><div style"margin-bottom: 10px">调用接口方法定义列表</div…

QT 带箭头的控件QPolygon

由于对当前项目需要绘制一个箭头控件&#xff0c;所以使用了QPainter和QPolygon来进行绘制&#xff0c;原理就是计算填充&#xff0c;下面贴出代码和效果图 这里简单介绍下QPolygon QPolygon是继承自 QVector<QPoint>那么可以很简单的理解为&#xff0c;他就是一个点的…

探索丹摩智算平台的奇妙之旅:我的CogVideoX实践实验与深刻体验

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀CogVideoX &#x1f4d2;1. 初识CogVideoX&#x1f4da;2. 部署与准备&#x1f31e;在丹摩智算平台上创建实例&#x1f338;CogVideoX代码仓库…

Linux基础命令——账户简单管理

一.添加用户 命令&#xff1a;useradd username eg:useradd yy 添加用户名为yy的用户 注意&#xff1a; inux中如果新建用户的时候没有用-d参数指定家目录&#xff0c;那么用户的家目录是什么? 指定的默认/home下面&#xff0c;以username命名 二.修改账户口令/密码 命令&…

漫步者头戴式耳机哪个型号好?热门主流头戴式耳机专业深度评测

一直以来头戴式蓝牙耳机凭借其独特的优势&#xff0c;逐渐成为了音乐爱好者、游戏玩家以及日常通勤者的首选&#xff0c;它们不仅融合了卓越的音质体验、便捷的无线连接&#xff0c;还融入了先进的降噪技术和人性化的佩戴设计&#xff0c;为用户带来了前所未有的听觉盛宴与舒适…

css实现居中的方法

水平居中 1. 行内设置text-align 给父元素设置text-align为center&#xff0c;一般用于实现文字水平居中 2. 给当前元素设置margin&#xff1a;0 auto 原理&#xff1a;块级独占一行&#xff0c;表现为在水平方向上占满整个父容器&#xff0c;当水平方向padding&#xff0c;…

500元以内头戴式耳机哪款好?盘点500元以内百元宝藏品牌机型推荐

作为耳机发烧友&#xff0c;我深知一副优质的头戴式耳机都能为我们带来沉浸式的听觉体验&#xff0c;但然而&#xff0c;面对市场上琳琅满目的耳机品牌和型号&#xff0c;500元以内头戴式耳机哪款好&#xff1f;对于这个问题我将为大家盘点500元以内百元宝藏品牌机型推荐无论你…

【chromedriver编译-绕过selenium机器人检测】

有小伙伴说使用selenium没能绕过机器人检测&#xff0c;盘他。 selenium机器人检测有2种&#xff0c;一是cdp检测&#xff0c;二是webdriver特征检测。cdp检测前面的博客已写过&#xff0c;这里就提下webdriver特征检测。一、selenium简介 Selenium 是一个强大的工具&#xff…

浅析OceanBase数据库的向量化执行引擎

本篇博客是偏数据库系统概念性的内容&#xff0c;不会深入到 OceanBase 中各个算子和表达式的在向量化中的详细设计和实现。 背景 为了提升OceanBase社区版用户解决问题的效率&#xff0c;OceanBase官方不久前推出了《OceanBase 从入门到实践》系列课程。在第七期直播课程后&a…

Linux笔记---简单指令

1. 使用的环境 博主使用的是华为云服务器xshell终端的方式学习的&#xff0c;因为据说这样的方式比较接近以后的工作环境。 其中云服务器安装的是Ubuntu操作系统(以Linux为内核&#xff0c;适合新手学习Linux的一个版本) 这里的云服务器不一定使用华为的&#xff0c;但是我在…

基于Spring JDBC AbstractRoutingDataSource 实现动态数据源

AbstractRoutingDataSource 实现动态数据源 AbstractRoutingDataSource 即抽象的路由数据源&#xff0c;提供了动态数据源切换的机制。你可以通过实现它的 determineCurrentLookupKey() 方法&#xff0c;根据不同的条件返回对应的数据源 key&#xff0c;基于这点可以根据外部输…

OpenRestry(一个Nginx集成工具)的安装与使用

文章目录 一、OpenRestry介绍1、什么是Nginx呢&#xff1f;2、Nginx的反向代理3、Nginx的作用4、什么是OpenRestry&#xff1f; 二、OpenRestry的安装三、OpenRestry中nginx的使用1、Ngnix可以当做web服务器2、Nginx中可以编写Lua脚本 一、OpenRestry介绍 要想了解什么是OpenR…

ChatGPT搭上langchain的知识库RAG应用,效果超预期

最近利用LangchainChatGPT实现了上传文档实现个人知识库应用的能力&#xff0c;效果比想象得要好。文末大家可以体验一下效果~~ 给大家大致介绍下实现方式&#xff0c;参考了Langchain chatchat。 一、LangchainChatGPT 1、概述 LangChain 是一个强大的框架&#xff0c;可以…