嵌入式系统文件系统

嵌入式文件系统


定义及功能

嵌入式文件系统是一种专为嵌入式系统设计的软件层,它提供了一种对非易失性存储器(如闪存、SD卡等)上数据进行有序组织和管理的方法。其主要功能包括文件的创建、读写、删除、目录管理等,使得用户可以像操作常规文件那样对存储器中的数据进行操作。

与通用文件系统的差异

相比通用操作系统中的文件系统,嵌入式文件系统设计更加关注资源的高效利用和稳定性。由于嵌入式系统资源有限,如内存较小、CPU性能较弱,因此嵌入式文件系统在设计时需要考虑存储空间的有效利用、低功耗、快速启动和故障恢复等方面。另外,嵌入式文件系统常常需要针对特定类型的存储媒介进行优化,以适应其特有的读写特性和寿命限制。


 嵌入式系统详解

在嵌入式领域,FLASH是一种常用的存储设备,Flash闪存作为嵌入式系统的主要存储设备有其自身的特性。Fash的写入操作只能把对应位置的1修改成0,而不能把0修改为1,而擦除Fash就是把对应存储块的内容恢复为1。因此,一般情况下,向Fash写入内容时,需要先擦除对应的存储区间,这种擦除是以块(Bock)为单位进行的。闪存主要有NOR和NAND两种技术。因为Flash存储器的擦写次数是有限的,NAND闪存还有特殊的硬件接口和读写时序,于是就出现了专门针对FLASH的文件系统。比较常用的有jffs2,yaffs2,logfs,ubifs。传统的文件系统如ext2、ext3、ntfs等都是针对机械式硬盘设计的,用作Fash文件系统会很多的弊端。

  在嵌入式Linux下,MTD(MemoryTechnology Device,存储技术设备)为底层硬件(闪存)和上层(文件系统)之间提供一个统一的抽象接口,即Flash的文件系统都是基于MTD驱动层。使用MTD驱动程序的主要优点在于,它是专门针对各种非易失性存储器(以闪存为主)而设计的,因而它对Flash有更好的支持、管理和基于扇区的擦除、读/写操作接口。另外,一块Flash芯片可以被划分为多个分区,各分区可以采用不同的文件系统;两块Flash芯片也可以合并为一个分区使用,采用一个文件系统。即文件系统是针对于存储器分区而言的,而非存储芯片。根据存储设备的不同,可以将嵌入式文件系统划分为三大类:基于flash的文件系统,基于内存的文件系统,基于网络的文件系统。

基于flash的文件系统

 jffs2:Journalling Flash FileSystem 

JFFS文件系统最早是由瑞典 Axis Communications公司基于Linux2.0的内核为嵌入式系统开发的文件系统。JFFS2是RedHat公司基于JFFS开发的闪存文件系统,最初是针对RedHat公司的嵌入式产品eCos开发的嵌入式文件系统,所以JFFS2也可以用在Linux, uCLinux中。

Jffs2: 日志闪存文件系统版本2 (Journalling Flash FileSystem v2) 主要用于NOR型闪存,基于MTD驱动层,特点是:可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等。缺点主要是当文件系统已满或接近满时,因为垃圾收集的关系而使jffs2的运行速度大大放慢。

目前jffs3正在开发中。关于jffs系列文件系统的使用详细文档,可参考MTD补丁包中mtd-jffs-HOWTO.txt。

jffsx不适合用于NAND闪存主要是因为NAND闪存的容量一般较大,这样导致jffs为维护日志节点所占用的内存空间迅速增大,另外,jffsx文件系统在挂载时需要扫描整个FLASH的内容,以找出所有的日志节点,建立文件结构,对于大容量的NAND闪存会耗费大量时间。

JFFS2 的优缺点如下:
优点:
    使用了压缩的文件格式。最重要的特性是可读写操作。
缺点:

    JFFS2 文件系统挂载时需要扫描整个 JFFS2 文件系统,因此当 JFFS2 文件系统分区增大时,挂载时间也会相应的变长。使用 JFFS2 格式可能带来少量的 Flash 空间的浪费。这主要是由于日志文件的过度开销和用于回收系统的无用存储单元,浪费的空间大小大致是若干个数据段。 JFFS2 的另一缺点是当文件系统已满或接近满时, JFFS2 运行速度会迅速降低。这是因为垃圾收集的问题。

注意:

    (1)日志结构文件系统并不采用本地更新的方式,而是采用异步更新的方式,即当某个数据块需要更新时,先找一个新块将新数据写入,再将旧块擦除。不过旧数据并不马上在闪存中擦除,而是以日志方式作为历史记录保存下来,这为文件系统的恢复操作打下了基础.

    (2)不适合用于NAND闪存的主要是因为NAND闪存的容量一般较大,这样导致jffs为维护日志节点所占用的内存空间迅速增大,另外jffs文件系统在挂载时需要扫描整个FLASH的内容,以找出所有的日志节点,建立文件结构,对于大容量的NAND闪存会耗费大量时间.

yaffs:Yet Another Flash File System


    yaffs/yaffs2 是专门为 NAND Flash 设计的嵌入式文件系统。它是日志结构的文件系统,提供了损耗平衡和掉电保护,可以有效地避免意外掉电对文件系统一致性和完整性的影响,。与jffs2相比,它减少了一些功能(例如不支持数据压缩),所以速度更快,挂载时间很短,对内存的占用较小。它是跨平台的文件系统,除了Linux和eCos,还支持WinCE, pSOS和ThreadX等。
yaffs/yaffs2 的优缺点如下:
优点:
    专门针对 NAND Flash,软件结构得到优化,速度快。
    使用硬件的 spare area 区域存储文件组织信息,启动时只需扫描组织信息,启动比较快。
    采用多策略垃圾回收算法,能够提高垃圾回收的效率和公平性,达到损耗平衡的目的。
缺点:

    没有采用压缩的文件格式。当包含的内容相同时, yaffs2 镜像文件要比 jffs2 镜像文件大。

注意:
    yaffs与yaffs2的主要区别在于,前者仅支持小页(512 Bytes)NAND闪存,后者则可支持大页(2KB) NAND闪存。同时,yaffs2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。与jffs2相比,它减少了一些功能(例如不支持数据压缩),所以速度更快,挂载时间很短,对内存的占用较小。

Cramfs:Compressed ROM File System


    Cramfs是Linux的创始人 LinusTorvalds参与开发的一种只读的压缩文件系统。它也基于MTD驱动程序。在cramfs文件系统中,每一页(4KB)被单独压缩,可以随机页访问,其压缩比高达2:1,为嵌入式系统节省大量的Flash存储空间,使系统可通过更低容量的FLASH存储相同的文件,从而降低系统成本。
    Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去运行,但这并不代表比Ramfs需求的RAM空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当我们读取的档案不在内存时,Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。另外,它的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性。    
    由于以上特性,Cramfs在嵌入式系统中应用广泛。但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容对进扩充。Cramfs映像通常是放在Flash中,但是也能放在别的文件系统里,使用loopback 设备可以把它安装别的文件系统里。

Romfs


    传统型的Romfs文件系统是一种简单的、紧凑的、只读的文件系统,不支持动态擦写保存,按顺序存放数据,因而支持应用程序以XIP(eXecute In Place,片内运行)方式运行,在系统运行时,节省RAM空间。uClinux系统通常采用Romfs文件系统。
    其他文件系统:fat/fat32也可用于实际嵌入式系统的扩展存储器(例如PDA,Smartphone, 数码相机等的SD卡),这主要是为了更好的与Windows桌面操作系统相兼容。ext2也可以作为嵌入式Linux的文件系统,不过将它用于 FLASH闪存会有诸多弊端。

基于RAM的文件系统

 ramfs


ramfs是一种非常简单的文件系统,它直接利用linux内核已有的高速缓存机制(所以其实现代码很小,也由于这个原因,ramfs特性不能通过内核配置参数屏蔽,它是内核的天然属性),使用系统的物理内存,做成一个大小可以动态变化的的基于内存的文件系统。
ramfs工作于虚拟文件系统层(VFS)层,不能被格式化,可以创建多个,默认情况下,ramfs最多能用到内存的一半,必要时也可以使用-o maxsize = 10000(单位是KB)来更改使用的最大内存量。
ramfs没有对应的文件系统设备,文件被写入ramfs和其他文件系统一样都正常分配页缓存和目录缓存,但是却不可能想其他有存储设备的文件系统一样将高速缓存中的文件回写到存储设备。这就意味着这些为ramfs中的文件和目录分配的高速页或者目录缓存都不可能会被标记为clean(可用)状态,所以系统就永远不会释放ramfs所占用的内存。正因为可以在ramfs下面可以一直往里写数据,直到写满为止,所以这种操作只有root(or trusted user)用户才可以进行ramfs写操作。
为了解决ramfs的缺点(没有回写设备)导致的种种问题,所以衍生出了tmpfs文件系统。

tmpfs


tmpfs是ramfs的衍生物,在ramfs的基础上增加了容量大小的限制和允许向交换
空间(swap) 写入数据。由于增加了这两个特性,所以普通用户也可以使用tmpfs。
tmpfs是一种虚拟内存文件系统,它不同于传统的用块设备形式来实现的ramdisk,也不同于针对物理内存的ramfs。tmpfs既可以使用物理内存,也可以使用交换分区。在linux内核中,虚拟内存资源由物理内存和交换分区组成,这些资源由内核中的虚拟内存子系统来负责管理。tmpfs就是和虚拟内存子系统打交道的,它向虚拟内存子系统请求页来存储文件,同linux的其他请求页的部分一样,不知道分配给自己的页是在内存中还是在交换分区中。也就是说tmpfs使用的是虚拟内存,而ramfs使用物理内存。另外tmpfs和ramfs一样,不可以被格式化,同时大小也是不固定的,可以使用-o size =32m或者(1g)来修改。
另外,tmpfs可以将当前不需要使用的页写入到交换空间。同时由于其使用的虚拟内存,所以tmpfs一旦被卸载,其中的数据都会丢失。
如果需要使用tmpfs,在内核编译的时候得选择上:
Virtual memory filesystem support
ramfs只会在物理内存中被创建,而tmpfs可能在物理内存中创建,也可能在交换 分区中创建。对于想利用内存的高速IO来提高效能的应用,最好是使用ramfs。对于只是想存放临时缓存的应用,最好使用tmpfs,以提高内存的使用率。

rootfs


rootfs是一个特定的ramfs(或tmpfs,如果tmpfs被启用)的实例,它始终存在于linux2.6的系统中。rootfs不能被卸载(与其添加特殊代码用来维护空的链表,不如把rootfs节点始终加入,因此便于kernel维护。rootfs是ramfs的一个空实例,占用空间极小)。大部分其他的文件系统安装于rootfs之上,然后忽略它。它是内核启动初始化根文件系统。

ramdisk


linux2.6版本之后都不在使用ramdisk了,2.4中还在使用。ramdisk是一种将内存
中的的一块区域作为物理磁盘来使用的一种技术,也可以说,ramdisk是在一块内存区 域中创建的块设备,用于存放文件系统。对于用户来说,可以把ramdisk与通常的硬盘分区同等对待来使用。ramdisk不适合作为长期保存文件的介质,掉电后ramdisk的内容会消失。
为了能够使用ramdisk 你的内核必须要支持ramdisk,即:在编译内核时,要选中RAM disk support这一选项,会在配置文件中定义CONFIG_BLK_DEV_RAM。同时为了让内核有能力在内核加载阶段就能装入ramdisk,并运行其中的内容,要选中initial RAM disk(initrd) support 选项,会在配置文件中定义CONFIG_BLK_DEV_INITRD。
ramdisk的大小是固定的,安装在其上的文件系统大小也是固定的。ramdisk在使用的时候,这个假的块设备和高速缓存(页缓存和目录缓存)之间有数据的拷贝,而且它还需要文件系统的驱动来格式化和解释这些数据。所以,使用ramdisk不仅浪费了内存,还加重了cpu的负担,同时也无污染了cache,而且其所有的文件和目录都要通过页和目录缓存进行访问,这些工作ramfs都要执行的,那么ramdisk就可以完全不需要。这是废弃ramdisk的理由之一。
另一个废弃它的理由就是,回环设备的引进,而回环设备提供了一个更灵活和方便的方式(从文件而不是从大块的内存)来创建一个合成块设备。

Ramdisk,ramfs/tmpfs

    Ramdisk是将一部分固定大小的内存当作分区来使用。它并非一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,并且可以作为根文件系统。将一些经常被访问而又不会更改的文件(如只读的根文件系统)通过Ramdisk放在内存中,可以明显地提高系统的性能。
    在Linux的启动阶段,initrd提供了一套机制,可以将内核映像和根文件系统一起载入内存。
    Ramfs是LinusTorvalds开发的一种基于内存的文件系统,工作于虚拟文件系统(VFS)层,不能格式化,可以创建多个,在创建时可以指定其最大能使用的内存大小。(实际上,VFS本质上可看成一种内存文件系统,它统一了文件在内核中的表示方式,并对磁盘文件系统进行缓冲。)
    Ramfs/tmpfs文件系统把所有的文件都放在RAM中,所以读/写操作发生在RAM中,可以用ramfs/tmpfs来存储一些临时性或经常要修改的数据,例如/tmp和/var目录,这样既避免了对Flash存储器的读写损耗,也提高了数据读写速度。
    Ramfs/tmpfs相对于传统的Ramdisk的不同之处主要在于:不能格式化,文件系统大小可随所含文件内容大小变化。
    Tmpfs的一个缺点是当系统重新引导时会丢失所有数据。
 

initrd、initramfs


 initrd出现的背景


在早期的linux系统中,一般只有硬盘或者软盘被用来作为linux根文件系统的存储设备,因此也就很容易把这些设备的驱动程序集成到内核中。但是现在的嵌入式系统中可能将根文件系统保存到各种存储设备上,包括scsi、sata,u-disk等等。因此把这些设备的驱动代码全部编译到内核中显然就不是很方便。
在内核模块自动加载机制udev中,我们看到利用udevd可以实现内核模块的自动加载,因此我们希望如果存储根文件系统的存储设备的驱动程序也能够实现自动加载,那就好了。但是这里有一个矛盾,udevd是一个可执行文件,在根文件系统被挂载前,是不可能执行udevd的,但是如果udevd没有启动,那就无法自动加载存储根文件系统设备的驱动程序,同时也无法在/dev目录下建立相应的设备节点。
为了解决这一矛盾,于是出现了基于ramdisk的initrd( bootloader initialized RAM disk )。Initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中必须的驱动模块,可执行文件和启动脚本,也包括上面提到的udevd(实现udev机制的demon)。当系统启动的时候,bootloader会把initrd文件读到内存中,然后把initrd文件在内存中的起始地址和大小传递给内核。内核在启动初始化过程中会解压缩initrd文件,然后将解压后的initrd挂载为根目录,然后执行根目录中的/init脚本(cpio格式的initrd为/init,而image格式的initrd<也称老式块设备的initrd或传统的文件镜像格式的initrd>为/initrc),您就可以在这个脚本中运行initrd文件系统中的udevd,让它来自动加载realfs(真实文件系统)存放设备的驱动程序以及在/dev目录下建立必要的设备节点。在udevd自动加载磁盘驱动程序之后,就可以mount真正的根目录,并切换到这个根目录中来。
这里只是个简单的描述,后面慢慢分析吧。

initrd的种类和制作


initrd总的来说目前有两种格式:image格式和cpio格式。image格式也叫文件系统镜像文件(老式块设备的initrd文件),主要在linux 2.4内核中使用流行;在linux 2.5内核开始引入initramfs技术,initramfs实际上已经克服了imgae-initrd的缺点,本质上也是cpio格式的initrd,只不过是和内核编译到了一个image文件,放在了.init.ramfs段内;到linux2.6的内核支持两种格式的initrd,即image-initrd和cpio-initrd,此时的cpio-initrd文件已不再编译进内核而单独成一文件,使用cpio工具生成。后边详述。

在介绍initrd的制作之前,先了解下面的几个命令作用:
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
1. if=文件名:输入文件名,缺省为标准输入。即指定源文件。< if=input file >
注意/dev/zero设备,这个设备是可以源源不断地提供0的设备,用来初始化
2. of=文件名:输出文件名,缺省为标准输出。即指定目的文件。< of=output file >
3.bs=bytes:同时设置读入/输出的块大小为bytes个字节。
4. count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
还有其他更详细的参数用法参考:dd命令-详解
http://blog.csdn.net/liumang_D/archive/2009/02/17/3899462.aspx

mkfs.ext2:等同于mke2fs,建立ext2文件系统。
mke2fs [-cFMqrSvV][-b <区块大小>][-f <不连续区段大小>][-i <字节>][-N ][-l <文件>][-L <标签>][-m <百分比值>][-R=<区块数>][ 设备名称][区块数]
1. -F 不管指定的设备为何,强制执行mke2fs。
2. -m<百分比值> 指定给管理员保留区块的比例,预设为5%。
3. 其余参数默认即可,参考: mkfs.ext2 命令-详解(网络搜索)
mount:挂在命令.
mount [-t vfstype] [-o options] device dir
1.-t vfstype 指定文件系统的类型,通常不必指定。mount 会自动选择正确的类型。
2.-o options 主要用来描述设备或档案的挂接方式。常用的参数有:
 loop:用来把一个文件当成硬盘分区挂接上系统
 ro:采用只读方式挂接设备
 rw:采用读写方式挂接设备
 iocharset:指定访问文件系统所用字符集
3.详细参数参考:mount命令详解(网络搜索)

1)、image-initrd制作
我们可以通过下面的方法来制作一个老式基于块设备的image-initrd文件:
# dd if=/dev/zero of=initrd.img bs=4k count=1024
# mkfs.ext2 -F –m 0 initrd.img
# sudo mkdir /mnt/ramdisk
# mount -o loop initrd.img /mnt/ramdisk
# cp -r /opt/filesystem /mnt/ramdisk
# umount /mnt
# gzip -9 initrd.img
通过上面的命令,我们制作了一个4M的initrd,其中/opt/filesystem就是我们用busybox制作的一个根目录。最后我们得到一个名为initrd.img.gz的压缩比最大的压缩文件。更加详细的过程,参考:ramdisk制作
http://blog.csdn.net/epicyong333/archive/2008/12/24/3590619.aspx
http://blog.csdn.net/vcvbve/archive/2010/02/27/5329384.aspx

利用image-initrd可以使内核在启动阶段可以顺利地完成各种存储介质的驱动的加载和realfs文件系统的挂载,然而image-initrd存在以下缺点:
1.image-initrd大小是固定的,例如上面的压缩之前的initrd大小是4M(4k*1024),假设您的根目录(上例中的/opt/filesystem)总大小仅仅是1M,它仍然要占用4M的空间。如果您在dd阶段指定大小为1M,后来发现不够用的时候,必须按照上面的步骤重新来一次。
2.image-initrd是一个虚拟的块设备,您可是使用fdisk对这个虚拟块设备进行分区。在内核中,对块设备的读写还要经过缓冲区管理模块,也就是说,当内核读取initrd中的文件内容时,缓冲区管理层会认为下层的块设备速度比较慢,因此会启用预读和缓存功能。这样initrd本身就在内存中,同时块设备缓冲区管理层还会保存一部分内容。

2)、initramfs
为了避免上述缺点,在linux2.5中出现了initramfs,它的作用和initrd类似,只是和内核编译成一个文件(该initramfs是经过gzip压缩后的cpio格式的数据文件),该cpio格式的文件被链接进了内核中特殊的数据段.init.ramfs上,其中全局变量__initramfs_start和__initramfs_end分别指向这个数据段的起始地址和结束地址。内核启动时会对.init.ramfs段中的数据进行解压,然后使用它作为临时的根文件系统。
要制作这样的内核,我们只需要在make menuconfig中配置以下选项就可以了:
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(/opt/filesystem) Initramfs source file(s)
其中/opt/filesystem就是我们的小型根目录,这里可以使一个现成的gzip压缩的cpio文件,也可以使一个目录,更可以是txt格式的配置文件,如下面的实例:
dir /dev 755 0 0
nod /dev/console 644 0 0 c 5 1
nod /dev/loop0 644 0 0 b 7 0
dir /bin 755 1000 1000
slink /bin/sh busybox 777 0 0
file /bin/busybox initramfs/busybox 755 0 0
dir /proc 755 0 0
dir /sys 755 0 0
dir /mnt 755 0 0
file /init initramfs/init.sh 755 0 0
如果指定的是一个目录而不是一个像这样的配置文件,内核在编译的时候会从指定的目录创建一个配置文件(usr/Makefile调用scripts/gen_initramfs_list.sh来生成),作为usr/gen_init_cpio.c文件的输入,最后生成一个usr/initramfs_data.cpio.gz文件,通过usr/initramfs_data.S包含到.init.ramfs段中去,最后生成zImage。

3)、cpio-initrd
这里所说的initrd格式和编译进内核的initramfs格式是一样的,都是cpio,也
被称为外部initramfs,它是独立存在的,需要bootloader将其加载进内存特定地址,然后将地址和大小传递给内核,在内核的初始化阶段来进行相应的处理。
这种initrd可以使用cpio命令来实现,如下:
# sudo find /opt/filesystem/ -depth | cpio -c -o > initrd.img
# gzip -9 initrd.img
这样得到的initrd就是cpio格式的,而且这个文件的大小是可变的,意思就是根据
你的filesystem的大小而变化,不会像前面的image格式的initrd那样大小固定了。当然我觉得前面的initramfs的大小也是可变的了。

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

    NFS是由Sun开发并发展起来的一项在不同机器、不同操作系统之间通过网络共享文件的技术。在嵌入式Linux系统的开发调试阶段,可以利用该技术在主机上建立基于NFS的根文件系统,挂载到嵌入式设备,可以很方便地修改根文件系统的内容。

    以上讨论的都是基于存储设备的文件系统(memory-basedfile system),它们都可用作Linux的根文件系统。实际上,Linux还支持逻辑的或伪文件系统(logical orpseudo file system),例如procfs(proc文件系统),用于获取系统信息,以及devfs(设备文件系统)和sysfs,用于维护设备文件。

构建嵌入式系统

做Linux系统开发其实大部分工作都是围绕根文件系统,因为uboot、kernel一般都是原厂提供,且外设官方也提供了驱动,移植就是了,本身开发工作不多。

构建根文件系统最难做到的就是版本符合且完整。因为根文件系统涉及到的需求、库、源文件等很多,而且还有版本要求因此并不容易。

根文件系统构建最麻烦的是opengl库、java库、qt库、tslib库、openvg库、Python库、sqlite等等。下面分别介绍几种不同的构建方法,阐述途径依旧是原料和工具、过程、输出。

Yocto是常见的构建根文件系统的工具,当然uboot和kernel一并能构建出来,但是大部分人只需要根文件系统。很多SOC厂比如NXP加入了Yocto计划整出Yocto版的SDK,这并不是什么好事,SOC用户更喜欢每一款芯片单独提供一个SDK然后配置编译。

Yocto构建原料和工具需要一台内存、主频、影盘比较高的电脑,还要Ubuntu环境和repo、git环境,一份SOC厂提供的Yocto包。

过程就是下载、build配置、编译,整个编译要十几个小时还跟电脑性能有关。输出就是交叉编译工具链、二进制的uboot和kernel、还有最重要的包含了需要的各种库的根文件系统。

buildroot也是SOC厂提供SDK的惯用方法,比如瑞芯微、STM32MP等。buildroot配置和编译比较简单过程也不复杂,整个过程像极了kernel的配置编译过程,编译速度也比较快,从SDK厂商处获得SDK后编译并不难。

busybox仅仅用于构建根文件系统,但是只有一些基本的东西比如shell、telnet等。编译过程跟编译kernel很像,也是先make menuconfig,然后配置最后编译。

在构建根文件系统时笔者认为宁多勿缺,很多人会觉得flash资源有限不适合放这么多库,但是既然选择用Linux了就不要用做MCU的思维来做了,如果资源真的受限应该用RTOS来做不要考虑上Linux。因为缺一两个库最后应用跑不起来重新构建一遍根文件系统是非常痛苦的。

另外Android移植没有大家想象的困难,一般能跑Android的SOC官方都会发布一个公版SDK的。Andriod的难度在于深度定制和应用开发,移植本身难度比Linux还要小。

1. Buildroot
定义:Buildroot是一个简化和加速嵌入式Linux系统开发过程的工具,提供一种容易、高效的方式来生成交叉编译工具链、根文件系统、内核映像和引导加载程序。Buildroot使用makefile和kconfig(和Linux内核使用的相同系统)来配置和构建整个嵌入式系统。

适用场景:对于需要轻量级或高度定制的嵌入式系统,Buildroot非常适合,尤其是那些资源受限或对启动时间有严格要求的环境。

2. Ubuntu
定义:Ubuntu是基于Debian的一种Linux发行版,以其用户友好而闻名,提供了图形用户界面(GUI)和丰富的软件库。它被广泛用于桌面、服务器甚至云计算环境,拥有强大的社区和商业支持。

适用场景:尽管Ubuntu主要用于桌面和服务器,但其LTS(长期支持)版本也可用于嵌入式开发,并在IoT(物联网)领域中日趋流行。

3. Debian
定义:Debian是一个非常古老和受尊敬的Linux发行版,以其稳定性、安全性和自由的原则著称。Ubuntu及许多其他发行版都是基于Debian构建的。

适用场景:Debian被广泛用于服务器和桌面,但也可以用作创建定制嵌入式系统的基础,尽管这不是它最常见的用途。

4. Yocto Project
定义:Yocto是一个强大的、灵活的开源项目,旨在帮助开发者创建定制的Linux系统,无论是用于产品原型开发还是商业产品。与Buildroot类似,Yocto提供了一个构建环境和工具链,但其特点是对复杂应用和大型系统的支持,提供了更多的灵活性和扩展性。

适用场景:当需要高度定制的嵌入式Linux系统,或是需要支持多个硬件平台且有复村的软件栈要求时,Yocto是一个非常好的选择。

注意事项:
值得注意的是,Yocto 和 Buildroot 本身并不是 Linux 发行版,它们只是帮助开发人员构建基于 Linux 的嵌入式系统(选择 Yocto,您可以构建 Linux 发行版;选择 Buildroot,您可以开发用于构建发行版的根文件系统)。

这是二者之间重要的区别之一,也体现了两个项目之间的差异,以及它们深受喜爱的原因。言归正传,让我们回到原定的主题上来。
 

它们之间的关系:
Buildroot vs Yocto:这两者都是为嵌入式Linux系统定制提供的工具,区别在于Buildroot更加轻量,而Yocto提供了更高的灵活性和扩展性。Buildroot适合小型或中等复杂性项目,Yocto更适合需要大量定制和支持多种硬件配置的复杂项目。
Ubuntu/Debian和Buildroot/Yocto:Ubuntu和Debian主要面向桌面和服务器市场,虽然也可以被用于嵌入式开发,但他们不提供Buildroot和Yocto那样针对嵌入式系统的高度定制能力。然而,Ubuntu和Debian提供丰富的包管理和软件库,适用于需要快速部署、且软件依赖性大的场景。
总结来说,Buildroot和Yocto更倾向于为嵌入式系统提供精细的定制能力和优化,而Ubuntu和Debian则服务于广泛的桌面和服务器市场,提供易用的操作系统环境和丰富的应用生态。选择哪一个取决于项目的具体需求、系统资源和预期的软件生态。

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值