Nand/Nor Flash

在嵌入式Linux产品中,通常使用的存储介质为Nand Flash和Nor Flash,而手机、相机等产品通常使用eMMC、SD Card作为存储介质,导致这种差异的原因主要是成本考量。

Nand Flash和Nor Flash具有低成本、高密度存储的优势。但是,它们在读写操作上又有各自的限制。Nand Flash和Nor Flash都没有片内FTL(Flash Transfer Layer)层,换句话说,它们都是raw flash。也就是说,本质上它们都是字符设备。未填写数据的时候,所有位都是高电平;写操作是将高电平变为低电平;只有擦操作才能将低电平变为高电平。所以Nand Flash和Nor Flash的写操作都只能通过先擦除再写入完成,读操作没有限制。

Nand Flash通常用来存储数据,它通过页(Page)和块(Block)两级结构组成,页大小通常为512Byte,类似于磁盘,块大小为8~32KB。读取和写入以页为单位进行,擦操作以块为单位进行。另外,针对每一页有16字节的OOB区,用来存放额外的信息以及ECC纠错码。Nand Flash比较容易出现坏块,其生命周期是擦写100万次。

Nor Flash通常用来存代码,因为它具有XIP(eXecute In Place)的特性,即片上执行,CPU可以把它当RAM使用,同时它也可以保存数据。Nor Flash的页大小通常为32Byte,块大小为128KB,芯片内部包含512Byte的写缓冲区。Nor Flash具有随机读和页读两种方式,擦除操作则是以块为单位,即128KB。Nor Flash在擦除操作之前,必须对每一位写0。Nor Flash的读速度比Nand Flash快,擦除和写入速度则比Nand Flash慢。另外,Nor Flash没有芯片内部的坏块处理,因为它比较少出现坏块,其生命周期是擦写10万次。

MTD(Memory Technology Devices) 

MTD子系统在raw flash上提供了一层抽象层,并提供统一的API接口给文件系统层,这样文件系统就不用关心实际的Flash类型是Nand Flash还是Nor Flash。

MTD子系统有以下三种接口:

1) mtd字符设备:/dev/mtd0, /dev/mtd1等,通常包括一组ioctl进行读取、擦除、写入、标记坏块、获取flash信息等操作

2) sysfs 参考Documentation/ABI/testing/sysfs-class-mtd

3) /proc/mtd

MTD子系统给文件系统层提供的API都在include/linux/mtd/mtd.h中描述,其中最重要的是mtd_info结构体。内核3.4版本之前,文件系统层通过mtd_info的成员函数指针调用接口函数;内核3.4版本以后,通过mtd.h文件中声明的mtd_read() mtd_write()等函数实现。

MTD既可以是字符设备,也可以是块设备。

mtdblock驱动是一个过时的工具,用来在mtd设备之上模拟块设备。它不进行坏块处理,所以不能用于Nand Flash。它的工作原理是通过缓存数据块来实现,修改操作在内存中缓存的数据块进行,然后擦除实际物理块,再将缓存的数据写入物理块。这样会出现掉电的时候,数据丢失的现象。另外,它也不进行wear-leveling和bit-flips(位反转)处理。通常将mtdblock理解为FTL层,其实这种认知是错误的,尽量不要使用mtdblock,除非你知道自己在干什么。

YAFFS/JFFS2/SQUASHFS/UBIFS

文件系统

mkimage

uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。

为什么uboot下会有这个工具呢?因为bootloader的类型有很多种,不同的bootloader在加载和启动内核时的方式大体上一致,但是具体实施上有细微的区别,mkimage的目的是在linux内核镜像文件(zImage)的基础上加上一段uboot可以识别的头部信息用来解析和加载内核镜像,通常最终生成的镜像文件名为uImage。该头部信息大小为0x40字节,记录mkimage参数所指定的信息,比如CPU体系结构、OS类型、镜像文件类型、内核镜像加载到内存的地址、压缩格式等。

Usage: ./mkimage -l image
          -l ==> list image header information
       ./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
          -A ==> set architecture to 'arch'
          -O ==> set operating system to 'os'
          -T ==> set image type to 'type'
          -C ==> set compression type 'comp'     //压缩格式,可选none/gzip/bzip2
          -a ==> set load address to 'addr' (hex)    //内核加载到内存的地址
          -e ==> set entry point to 'ep' (hex)      //内核加载到内存的地址+0x40       (跳过0x40的头部,该参数可以忽略)
          -n ==> set image name to 'name'
          -d ==> use image data from 'datafile'
          -x ==> set XIP (execute in place)
       ./mkimage [-D dtc_options] -f fit-image.its fit-image
       ./mkimage -V ==> print version information and exit

参数说明:
-A 指定CPU的体系结构:
取值 表示的体系结构
alpha Alpha
arm A RM
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系统类型,可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T 指定映象类型,可以取以下值:
standalone、kernel、ramdisk、multi、firmware、、filesystem
-C 指定映象压缩方式,可以取以下值:
none 不压缩
gzip 用gzip的压缩方式
bzip2 用bzip2的压缩方式
-a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载
-e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)
-n 指定映象名
-d 指定制作映象的源文件

示例:mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img

vmlinux/Image/zImage

LD      vmlinux                          内核编译完成之后,链接各目标文件,生成ELF格式vmlinux
SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY
arch/arm/boot/Image                通过objcopy提取vlinux中的代码段和数据段并打包生成arch/arm/boot/Image
  Kernel:
arch/arm/boot/Image is ready
  AS      arch/arm/boot/compressed/head.o
  GZIP   
arch/arm/boot/compressed/piggy.gz
  AS      arch/arm/boot/compressed/piggy.o
  CC     
arch/arm/boot/compressed/misc.o
  AS     
arch/arm/boot/compressed/head-xscale.o
  LD     
arch/arm/boot/compressed/vmlinux       通过gzip压缩arch/arm/boot/Image并添加解压程序等生成ELF格式的arch/arm/boot/compressed/vmlinux
  OBJCOPY
arch/arm/boot/zImage      通过objcopy提取arch/arm/boot/compressed/vmlinux中的代码段和数据段生成可以放在内存任意地址直接执行的arch/arm/boot/zImage

嵌入式Linux文件系统知多少的更多相关文章

  1. 制作嵌入式linux文件系统(ramdisk,cramfs,squashfs)

    转:http://blog.csdn.net/zyb19831212/article/details/1887930 一.什么是文件系统 (Filesystem): A directory struc ...

  2. 【嵌入式 Linux文件系统】如何使用Initramfs文件系统

    (1)#cd ../rootfs/ #ln -s ./bin/busybox init 创建软链接 (2)进入Linux内核 #make menuconfig General setup-->I ...

  3. 【嵌入式 Linux文件系统】如何使用NFS文件系统

    (1)内核配置 取消选项 General setup-->Initial RAM filesystem and RAM disk (initramfs/initrd) support 进入Fil ...

  4. X86平台下嵌入式linux触摸屏解决方案(usb触摸屏控制器+完美校准方案+触摸屏QTE开发环境搭建)

    一直在用X86平台,真心不想用WINCE和XPE,一些大的硬件供应商都不提供linux平台下的技术支持,比如研华的3343PC104系列的板子... 开发的问题如下: 1 USB控制器目前只有台湾和竹 ...

  5. 【课程分享】深入浅出嵌入式linux系统移植开发 (环境搭建、uboot的移植、嵌入式内核的配置与编译)

    深入浅出嵌入式linux系统移植开发 (环境搭建.uboot的移植.嵌入式内核的配置与编译) 亲爱的网友,我这里有套课程想和大家分享,假设对这个课程有兴趣的,能够加我的QQ2059055336和我联系 ...

  6. 【转】嵌入式Linux文件系统启动脚本及分析

    原文网址:http://www.linuxidc.com/Linux/2011-03/33728.htm 在内核初始化完成后,嵌入式linux 文件系统的启动过程主要包含以下几个步骤: 1. 执行/s ...

  7. 嵌入式linux加载引导内核和根文件系统的方法

    总体来说,嵌入式Linux内核和根文件的引导与PC机差不多.嵌入式linux内核和根文件系统可以存放在各种可能的存储设备中,一般情况下我 们将内核和根文件系统直接烧入到Flash中(包括NOR和NAN ...

  8. 嵌入式linux内核制作、根文件系统制作

    嵌入式系统构成: 主要由bootloader.kernel.以及根文件系统三部分组成. 内核制作步骤: 制作嵌入式平台使用的linux内核制作方法与pc平台上的linux内核基本一致 1.清除原有配置 ...

  9. 嵌入式Linux内核+根文件系统构建工具-Buildroot 快速入手指导【转】

    本文转载自:https://my.oschina.net/freeblues/blog/596448 嵌入式Linux内核+根文件系统构建工具-Buildroot 快速入手指导 buildroot 是 ...

随机推荐

  1. 由于;引发的Oracle的BadSqlExecption

    一.在使用单引号进行各种转换合并的时候发生的异常: 1:首先单引号的表示符为 ' 在Oracle中如果SQL语句带上了分号是会报错的, 在SQL传入进行执行的时候会报BadSQLExecption,这 ...

  2. tarjan算法应用 割点 桥 双连通分量

    tarjan算法的应用. 还需多练习--.遇上题目还是容易傻住 对于tarjan算法中使用到的Dfn和Low数组. low[u]:=min(low[u],dfn[v])--(u,v)为后向边,v不是u ...

  3. linux基本命令vi和vim使用详细介绍

    vi使用方法详细介绍 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版 ...

  4. vue 防抖和节流

    函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时. 函数节流(throttle):当持续触 ...

  5. mock.js模拟ajax数据请求

    在我们开发过程中存在着前端页面ui完成了,但是没有接口进行联调数据的情况,现在介绍一下用mock.js来完成数据的请求.这样在后期我们的后台接口完成后只需要更改请求的接口名字即可!前提是你的模拟字段名 ...

  6. libevent 网络库安装

    ./configure prefix=/tools/libevent make sudo make install

  7. 【学习】020 Redis

    Java缓存机制 Java中要用到缓存的地方很多,首当其冲的就是持久层缓存,针对持久层谈一下:  要实现java缓存有很多种方式,最简单的无非就是static HashMap,这个显然是基于内存缓存, ...

  8. ubuntu16.04下docker安装和简单使用(转)

    ubuntu16.04下docker安装和简单使用   转自:https://www.cnblogs.com/hupeng1234/p/9773770.html 前提条件 操作系统 docker-ce ...

  9. List中的Map

    List中的Map import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.u ...

  10. CSS3文本阴影、边框阴影

    CSS3添加阴影 一.使用text-shadow属性为文本添加阴影 二.使用box-shadow属性为边框添加阴影 一.为文本添加阴影 text-shadow     使用text-shadow,可以 ...