ROMFS文件系统分析

2023-05-16

ROMFS文件系统分析

ROMFS是一种简单的只读文件系统,主要是用来当做初始文件系统来使用的,在嵌入式linux或是uclinux中通常使用这中文件系统来作为引导系统的文件系统,甚至uclinux有时就直接把ROMFS作为其根文件系统,而不是将其作为系统启动中的过渡文件系统。在前面我也分析过,linux操作系统启动中一个是要加载内核,另一个就是要加载一个用于系统简单初始化的文件系统。这个文件系统的格式也是经过了很多发展的。现在一般使用的是一中cpio的格式。在嵌入式系统中一般使用romfs+其它的可读文件系统。romfs由于它的小巧性(其内核编译只有4000字节),所以非常适合作为系统启动初始化的文件系统。本文就是对ROMFS文件系统进行结构上的分析。前面我也曾对其源代码结构进行了简单的分析。关于ROMFS最为权威的资料是内核源代码树下的“Documentation/filesystems/romfs.txt”。本文多数资料就是来自于该文件。

ROMFS文件系统的制作

一般我们可以使用一些工具来制作ROMFS的文件系统。制作好之后其实也就是一个二进制的文件。制作工具一般使用”genromfs“,这个工具在网上就可下载到,其源代码并不是很多,只有不到900行。
以下是genromfs工具所支持的参数:

xux@zhwen:~/fs-sys$ genromfs -h
genromfs 0.5.2
Usage: genromfs [OPTIONS] -f IMAGE
Create a romfs filesystem image from a directory

  -f IMAGE               Output the image into this file
  -d DIRECTORY           Use this directory as source
  -v                     (Too) verbose operation
  -V VOLUME              Use the specified volume name
  -a ALIGN               Align regular file data to ALIGN bytes
  -A ALIGN,PATTERN       Align all objects matching pattern to at least ALIGN bytes
  -x PATTERN             Exclude all objects matching pattern
  -h                     Show this help

Report bugs to chexum@shadow.banki.hu
xux@zhwen:~/fs-sys$ 
  
参数解释:
-f IMAGE     指定输出romfs映像的名字
-d DIRECTORY 指定源目录(将该目录制作成romfs文件系统)
-v           显示详细的创建过程
-V VOLUME    指定卷标
-a ALIGN     指定普通文件的对齐边界(默认为16字节)
-A ALIGN,PATTERN 匹配参数PATTERN的对象对齐在ALIGN边界上
-x PATTERN 不包括匹配PATTERN的对象。
-h 显示帮助文档。
以下是如何制作生成一个romfs的文件系统:

xux@zhwen:~/fs-sys$ ls
test  
xux@zhwen:~/fs-sys$ ls test/
test  xux  zhwen
xux@zhwen:~/fs-sys$ genromfs -V "xromfs" -f romfs.img -d test
xux@zhwen:~/fs-sys$ ls
romfs.img  test 
xux@zhwen:~/fs-sys$ file romfs.img 
romfs.img: romfs filesystem, version 1 592 bytes, named xromfs.
xux@zhwen:~/fs-sys$ sudo mount romfs.img /mnt -o loop
xux@zhwen:~/fs-sys$ ls /mnt/
test  xux  zhwen
xux@zhwen:~/fs-sys$ 
  

ROMFS文件系统结构分析

ROMFS系统中最大文件的大小理论上可以达到4G,文件名的大小一般小于16字节,而且整个文件系统都是以16字节来对齐。
其结构如下:

offset      content
        +---+---+---+---+
  0     |  -  |  r  |  o  | m  |          +---+---+---+---+    The ASCII representation of those bytes
  4     |  1  |  f  |  s  |  -  |  /    (i.e. "-rom1fs-")
        +---+---+---+---+
  8     |     full size       |    The number of accessible bytes in this fs.
        +---+---+---+---+
 12     |    checksum   |       The checksum of the FIRST 512 BYTES.
        +---+---+---+---+
 16     |  volume name     |    The zero terminated name of the volume,
        :               :       padded to 16 byte boundary.
        +---+---+---+---+
 xx     |     file      |
        :    headers    :
  

File headers之前的字节由如下的数据结构来控制:include/linux/romfs_fs.h


/* On-disk "super block" */
struct romfs_super_block {
        __be32 word0;
        __be32 word1;
        __be32 size;
        __be32 checksum;
        char name[0];           /* volume name */
};
  
(1)这个数据结构中的word0和word1的是固定的值:“-rom1fs-”,由如下的宏定义说明:
include/linux/romfs_fs.h

#define ROMSB_WORD0 __mk4('-','r','o','m')
#define ROMSB_WORD1 __mk4('1','f','s','-')
  
(2)而size是对整个文件系统的大小的说明。
(3)checksum是对前512个字节的校验和(如果小于512,就以实际大小计算)。
(4)name是当前这个文件系统的名称。

下面在来看文件的堆放格式


offset      content
        +---+---+---+---+
        |     file header    |      
        +---+---+---+---+      
        |      file date     |      
        +---+---+---+---+      
        |     file header    |      
        +---+---+---+---+      
        |      file date     |      
        |     file header    |      
        +---+---+---+---+      
        |      file date     |      
        +---+---+---+---+      
        |      …….        |      
        +---+---+---+---+      
  

File header的格式如下


offset      content
        +---+---+---+---+
  0     | next filehdr   | X  |       The offset of the next file header
        +---+---+---+---+         (zero if no more files)
  4     |   spec.info       |       Info for directories/hard links/devices
        +---+---+---+---+
  8     |        size       |       The size of this file in bytes
        +---+---+---+---+
 12     |    checksum     |       Covering the meta data, including the file
        +---+---+---+---+         name, and padding
 16     |    file name      |       The zero terminated name of the file,
        :                    :       padded to 16 byte boundary
  
在内核源代码中如下:include/linux/romfs_fs.h

/* On disk inode */
struct romfs_inode {
        __be32 next;            /* low 4 bits see ROMFH_ */
        __be32 spec;
        __be32 size;
        __be32 checksum;
        char name[0];
};
  
(1)其中next的前面28位是指向下一个文件的地址,应为整个文件系统以16字节对齐,所以任何一个文件的起始地址的最后4位始终为“0”。
而这最后的4位并没就此浪费,而是进行了新的利用--指定文件的类型和是否可执行。在linux下文件的类型分为:目录,一般文件,链接文件,管道文件,设备文件等。所以这4位中的最高一位使用来表示该文件是否可执行,而其余三位使用来表示该文件的类型。
include/linux/romfs_fs.h

#define ROMFH_TYPE 7
#define ROMFH_HRD 0
#define ROMFH_DIR 1
#define ROMFH_REG 2
#define ROMFH_SYM 3
#define ROMFH_BLK 4
#define ROMFH_CHR 5
#define ROMFH_SCK 6
#define ROMFH_FIF 7
#define ROMFH_EXEC 8
  
(2)spec这个字段存放的是目录/硬链接/设备文件的相关信息:
这个域是文件类型相关的,也就是说对于不同的文件类型,这个域表示的含义是不一样的。下面是具体的说明;来自“Documentation/filesystems/romfs.txt”。

          mapping               spec.info means
 0      hard link       link destination [file header]
 1      directory       first file's header
 2      regular file    unused, must be zero [MBZ]
 3      symbolic link   unused, MBZ (file data is the link content)
 4      block device    16/16 bits major/minor number
 5      char device                 - " -
 6      socket          unused, MBZ
 7      fifo            unused, MBZ
  
(3)size是这个文件的大小。
(4)checksum这个域只是文件头和文件名的校验和。

(5)name是文件的名称。



认识romfs文件系统

1.1 什么是romfs

       romfs是一个只读文件系统,主要用在 mainly for initial RAM disks of installation disks.使用romfs文件系统可以构造出一个最小的内核,并且很节省内存。相比而言,早期的minixxiafs(现在已经过时)文件系统如果编译为模块的形式则大小超过20000字节(在x86机器上大小为38502字节),而romfs却小于一页(在linux系统中,一页大小为PAGE_OFFSET,一般为4K),大约4000字节(在x86机器上大小为10479字节)。在相同的条件下,msdos文件系统模块大约30K(并且不支持设备节点和符号链接,在x86机器上大小为12K)。ntfsnfsroot文件系统模块大约57K(在x86机器上大小为102K)。

注:上面叙述中的数值都是针对i586机器,括号中叙述的数值是在现在的x86机器上的大小,针对2.6.28内核。

1.2 romfs的用途

   romfs本设计的主要目标是构造一个最小内核,在内核中只链接romfs文件系统,这样就可以使用romfs在稍后加载其他模块。romfs也可以用来运行一些程序,从而决定你是否需要SCSI设备,或者IDE设备,或者如果你使用的是"initrd"结构的内核,romfs也可以用来在之后加载软驱驱动。romfs的另一个用途是在你使用romfs文件系统的时候,你可以关闭ext2或者minix甚至affs文件系统直到你确信需要的时候再开启。

1.3 romfs的性能

       romfs的操作是基于块设备的,它的底层结构非常简单。为了快速访问,每个单元被设计为起始于16字节边界。一个最小的文件为32字节(文件内容为空,并且文件名长度小于16字节)。对于一个非空文件的最大的开销是位于文件内容前面的文件头和其后的16字节的文件名(因为大多数的文件名长度大于3字节并且小于15字节,所以预置文件名长度为16字节)。

1.4 如何使用romfs映像

   要使用一个制作好的romfs格式的映像,是将其挂载在其他文件系统的某个节点上。并且还有一个很重要的前提,就是内核要支持romfs文件系统。这一点可以通过配置内核实现,有两个方法:

1.romfs配置成直接编译进内核,方法为使用make menuconfig命令进入内核配置界面,选择"File systems"并进入,选择“Miscellaneous filesystems”并进入,选择“ROM file system support(ROMFS)”,将其配置成"*"(直接编译进内核)。这样生成的内核就直接包含对romfs文件系统的支持。

2.romfs配置成模块的形式,步骤和前面一样,只是在最后选择"ROM file system support(ROMFS)"的时候将其配置成"M"(编译为内核模块)。这样编译好的内核并不包含对romfs文件系统的支持,只是生成了romfs.ko模块(fs/romfs/romfs.ko),需要在启动系统后将其加载进内核才能使内核支持romfs文件系统。

有了内核对romfs文件系统的支持,就可以直接挂载romfs格式的映像了,挂载方法为:

niutao@niutao:~/kernel/romfs$ ls

hello.img

niutao@niutao:~/kernel/romfs$ file hello.img

hello.img: romfs filesystem, version 1 208 bytes, named rom 49e05ac0.

niutao@niutao:~/kernel/romfs$ sudo mount -o loop hello.img /mnt

niutao@niutao:~/kernel/romfs$ cd /mnt/

niutao@niutao:/mnt$ ls

hello.c

niutao@niutao:/mnt$

  可以看到使用mount命令将hello.img挂载到了/mnt目录下,其内只有一个文件。

  卸载一个已经被挂载的romfs格式映像使用umount命令。

1.5 如何制作romfs映像

     如果要创建一个romfs文件系统,需要使用genromfs工具。具体用法为:

-f IMAGE     指定输出romfs映像的名字

-d DIRECTORY 指定源目录(将该目录制作成romfs文件系统)

-v           显示详细的创建过程

-V VOLUME    指定卷标

-a ALIGN     指定普通文件的对齐边界(默认为16字节)

-A ALIGN,PATTERN 匹配参数PATTERN的对象对齐在ALIGN边界上

-x PATTERN 不包括匹配PATTERN的对象。

-h 显示帮助文档。

下面一一解释每个参数的含义。

1.5.1  -f参数

   该参数指定要生成的romfs映像的名字,是一个必须参数,如果缺少,则无法生成映像。例如:

niutao@niutao:~/kernel/romfs$ ls

hello.c

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img

niutao@niutao:~/kernel/romfs$ ls

hello.c  hello.img

  可以看到生成了名为hello.imgromfs格式的映像。那么genromfs是将那个目录制作成了hello.img?将hello.img挂载之后,可以看到其内的文件为当前路径下的文件(hello.chello.img)。所以在没有指定源目录(要将那个目录制作成romfs映像)的时候,默认为当前目录。这一点也可以从genromfs的源代码中看到:

701 int main(int argc, char *argv[])

702 {

703         int c;

704         char *dir = ".";

705         char *outf = NULL;

706         char *volname = NULL;

注:代码摘自genromfs-0.5.2/genromfs.c

可以看到其中的dir就是指定的源目录,默认为当前目录。那么如何指定源目录?通过使用-d参数指定。

1.5.2  -d参数

   该参数指定源目录,意思是要将那个目录及其下面的文件制作成romfs格式的映像。如果不使用-d参数指定,则默认为当前目录。例如:

niutao@niutao:~/kernel/romfs$ ls

hello

niutao@niutao:~/kernel/romfs$ ls hello/

hello.c

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/

niutao@niutao:~/kernel/romfs$ ls

hello  hello.img

niutao@niutao:~/kernel/romfs$

1.5.3  -v参数

       -v表示显示romfs映像创建的详细过程。例如:

niutao@niutao:~/kernel/romfs$ ls

hello

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/ -v

0    rom 49e06097         [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0

1    .                    [0x80e     , 0x1e4204  ] 0040755, sz     0, at 0x20   

1    ..                   [0x80e     , 0x1e41ea  ] 0040755, sz     0, at 0x40     [link to 0x20    ]

1    hello.c              [0x80e     , 0x1e4266  ] 0100644, sz    71, at 0x60   

niutao@niutao:~/kernel/romfs$ ls

hello  hello.img

niutao@niutao:~/kernel/romfs$

1.第一列为目录深度(0为顶极目录),各项的含义具体见genromfs.cshownode函数。

2.第二列为文件或者目录名。

3.第三列为前一个为文件或者目录所在设备的设备号,后一个为文件或者目录的节点号(这两个对应struct stat结构体的st_dev项和st_ino项)。

4.第四列为文件或者目录的属性(对应struct stat结构体的st_mode项)。

5.第五列为文件或者目录的大小,对于目录为0,文件则为文件以字节为单位的大小。

6.第六列为文件或者目录在生成的romfs格式映像文件中的偏移。

7.第七列表示该文件或者目录是一个硬链接,其指向的位置。这里需要注意一个细节:对于顶极目录下的目录,..目录是一个硬链接,除此之外,所有的目录都是目录(也就是说此第七列对于顶极目录下的目录就不存在)。而对于顶极目录下的子目录内的目录,则都是硬链接。这个在往后还会继续从代码的角度分析为什么会是这样(见对genromfs工具的分析)。

1.5.4  -V参数

    指定当前要生成的romfs格式映像的卷标,如果没有指定,则默认为字符串"rom "加当前的时间(16进制格式)。例如:

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/

niutao@niutao:~/kernel/romfs$ ls

hello  hello.img

niutao@niutao:~/kernel/romfs$ file hello.img

hello.img: romfs filesystem, version 1 256 bytes, named rom 49e069d8.

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/ -V niutao

niutao@niutao:~/kernel/romfs$ file hello.img

hello.img: romfs filesystem, version 1 256 bytes, named niutao.

niutao@niutao:~/kernel/romfs$

1.5.5  -a参数

   指定普通文件的对齐边界(默认为16字节),目的是为了快速访问文件内容。给出的对齐边界值必须大于16并且为16的倍数。这里所说的对齐指的是普通文件的文件内容的对齐,而并非文件头(见内核include/linux/romfs_fs.h中结构体struct romfs_inode )的对齐。假如指定普通文件x的对齐边界为align,其在生成的romfs格式映像中的偏移为start,文件名长度为len,则文件内容在romfs映像中的偏移offset为:

offset = start + 16 + (len / 16) * 16 + len % 16 ? 16 : 0

其计算过程为文件头偏移加上文件头大小(struct romfs_inode),其文件头大小为16字节,再加上文件名以16字节对齐的长度。

例如:

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/ -V niutao -a 64 -v

0    niutao               [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0

1    .                    [0x80e     , 0x1e4204  ] 0040755, sz     0, at 0x20   

1    ..                   [0x80e     , 0x1e41ea  ] 0040755, sz     0, at 0x40     [link to 0x20    ]

1    hello.c              [0x80e     , 0x1e4266  ] 0100644, sz    71, at 0x60   

niutao@niutao:~/kernel/romfs$

我们使用-a参数指定普通文件的对齐algin = 64。可以看到普通文件hello.c文件头(也叫节点)开始偏移为start = 0x60,文件名长度len = 7,则文件内容起始位置offset为:

offset = start + 16 + (len / 16) * 16 + len % 16 ? 16 : 0

       = 0x60 + 16 + (7 / 16) * 16 + 7 % 16 ? 16 : 0

       = 0x80

其正好对齐在64边界上。

注意:-a参数只对普通文件起作用,如果要对所有或者部分或者指定的文件起作用,则要使用-A或者-x参数。

1.5.6  -A参数

       genromfs -A ALIGN,PATTERN

匹配PATTERN的对象对齐在ALIGN边界上。给出的对齐边界值必须大于16并且为16的倍数。和-a不同的是,-A参数可以指定某个文件或者某些文件对其在ALIGN边界上。例如:

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/  -v -A 64,.

0    rom 49e08490         [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0

1    .                    [0x80e     , 0x1e4204  ] 0040755, sz     0, at 0x40   

1    ..                   [0x80e     , 0x1e41ea  ] 0040755, sz     0, at 0x60     [link to 0x40    ]

1    hello.c              [0x80e     , 0x1e4266  ] 0100644, sz    71, at 0x80   

niutao@niutao:~/kernel/romfs$

指定目录"."对齐在64字节边界上。

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/  -v -A 64,*.c

0    rom 49e08553         [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0    

1    .                    [0x80e     , 0x1e4204  ] 0040755, sz     0, at 0x20   

1    ..                   [0x80e     , 0x1e41ea  ] 0040755, sz     0, at 0x40     [link to 0x20    ]

1    hello.c              [0x80e     , 0x1e4266  ] 0100644, sz    71, at 0x60   

niutao@niutao:~/kernel/romfs$

指定所有的.c文件对其在64字节边界上。

1.5.7  -x参数

不包括匹配PATTERN的对象。也就是说在生成romfs格式映像的时候,不包括指定的源目录下的匹配PATTERN的文件或者目录。例如:

niutao@niutao:~/kernel/romfs$ ls -al hello

total 12

drwxr-xr-x 2 niutao niutao 4096 2009-04-11 20:02 .

drwxr-xr-x 3 niutao niutao 4096 2009-04-11 19:49 ..

-rw-r--r-- 1 niutao niutao    0 2009-04-11 20:02 aa.c

-rw-r--r-- 1 niutao niutao   71 2009-04-11 16:54 hello.c

niutao@niutao:~/kernel/romfs$ genromfs -f hello.img -d hello/  -v -x hello.c

0    rom 49e086ed         [0xffffffff, 0xffffffff] 37777777777, sz     0, at 0x0    

1    .                    [0x80e     , 0x1e4204  ] 0040755, sz     0, at 0x20   

1    ..                   [0x80e     , 0x1e41ea  ] 0040755, sz     0, at 0x40     [link to 0x20    ]

1    aa.c                 [0x80e     , 0x1e4276  ] 0100644, sz     0, at 0x60

可以看出,我们使用-x参数将hello.c文件过滤掉了,在生成的romfs格式的映像中,没有hello.c


Romfs文件系统结构很简单,由两部分组成,超级块、文件信息。超级块占文件系统的开始32字节;
接着是32字节的文件头,接着是该文件的数据。每个文件头都是32字节,16字节边缘对齐。
a.超级块:
   0~7前八个字节是romfs文件系统标示,如” -rom1fs-”;8~11共4字节是romfs文件系统的大小,由此理解
romfs文件系统最大是4GB。接着4字节12~15是checksum.接着16个字节16~31是卷名,卷名是以空字符
结束的字符串,可在生成romfs文件系统时指定。
b.文件信息
    文件信息由32的字节文件头和文件数据组成。文件头组成如下:4字节下一文件头偏移量,4字节
spec.info,4字节文件大小,4字节checkshum,16字节文件名。
    每个文件头32个字节长,对齐于16字节边界。文件头前4字节是下一个文件头的偏移量和文件模式
信息。把4字节的最低4位置为0既是下一个文件头偏移量。文件头偏移量是从文件系统开始偏移。低
4位是文件模式信息,0~3位指示文件类型,第4位指示该文件是否可执行。文件类型如下:  
值     文件类型     Spec.info意义
0     硬链接(hard link)     link destination [file header]
1     目录     该目录下第一个文件头偏移量
2     一般文件     无意义,全0
3     符号连接(symbolic link)     无意义
4     块设备     16位主设备好和16位次设备号。
5     字符设备     16位主设备好和16位次设备号。
6     套接字文件     无意义
7     管道文件     无意义

c.简单例子 
 
   下面是一个romfs文件系统的开始部分内容。前8字节'2D 72 6F 6D 31 66 73 26’ 即是romfs文件系统标示”-romfs-”。'00 00 52 40’是文件系统大小,
即21056字节。'A0 30 35 C9’是checksum。接下来16字节卷名'52 4F 4D 64 69 73 6B 00 。。。’,即
”ROMdisk”。接下来的32字节就是第一个文件头。
'00 00 00 49 00 00 00 20 00 00 00 00 D1 FF FF 97 2E 00 00 …’. ’00 00 00 49’是下一文件偏移量,即
'00 00 00 40’是下一个文件头的位置;低4位是9即表示本文件是目录,是可以执行的。接下来的4
字节’00 00 00 20’,是目录的第一个文件头位置,即20h,指向了本身。接下来的4字节文件程度
'00 00 00 00’,表示该文件程度是0.接下来16字节文件名'2E 00 00 00…’,文件名为”.”。下一文件
头在40h,即’00 00 00 60 00 00 00 20 00 00 00 00 D1 D1 FF 80 2E 2E 00 00 …’。前4字节’00 00 00 60’
表示该文件是一个硬件链接,下一个文件头在60h。硬件链接指向的文件头在'00 00 00 20’,文件
大小是0,文件名是“..”。60h偏移量的文件头信息
'00 00 4D 2A 00 00 00 00 00 00 4C 9C 36 99 F4 C5 64 65 71 75 65 00 00 …’。表示下一个文件头偏移
量4D20h,当前文件是可执行文件,文件类型是一般文件;文件大小是19612字节;文件名
是“deque”。
制作romfs文件系统映像
genromfs是制作romfs文件系统映像的工具。把需要制作映像的文件放在一个目录下,如romfs目录下。
执行命令:genromfs –v –V “ROMdisk” –f romfs.img –d ./romfs。-f指定生成的镜像名,-d指定需要生成
镜像的目录名。
Romfs文件系统测试
可以把romfs文件系统镜像链接到c代码中,然后在程序中直接操作romfs文件中的数据。把镜像文件链
接成.o文件。ld –r –b binary romfs.img –o romfs.o. romf.o引出符号
_binary_romfs_img_start和_binary_romfs_img_end,这两个符号是字符数组类型,_binary_romfs_img_start
是romfs文件系统数据开始指针,_binary_romfs_img_end是结束指针。通过这个两个符号就可以对文件
系统数据进行操作。例如以下代码
extern D_INT8 _binary_romfs_img_start[];
extern D_INT8 _binary_romfs_img_end[];
/**根据文件名返回该文件的文件头在文件系统中的偏移量**/
D_INT8 *srv_get_romfs_file_head(D_INT8* filename, D_UINT8* start_head, D_UINT16 len, D_UINT32 os)
{
   D_UINT32 offset=0;
   D_UINT32 tmp;
   D_UINT16 i;
 
   offset = os;
   while( _binary_romfs_img_start+offset < _binary_romfs_img_end )
   {
        //printf(”filename=%s, curr=%s\n”, filename,start_head+offset+16);
        if( len == strlen(start_head+offset+16) && memcmp(filename, start_head+offset+16, len) == 0 )
                         return start_head+offset;
              tmp = 0;
           for(i=0; i< 4; i++)
        {
           tmp <<= 8;
           tmp += start_head[offset+i];
        }
        offset = tmp;
        offset &= 0xfffffff0;
        if( offset == 0 )
          break;
   }
   return NULL;
}
把romfs.o文件和相应的代码编译,通过_binary_romfs_img_start就可以读取romfs映像中的文件数据。

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

ROMFS文件系统分析 的相关文章

  • H3C链路聚合

    实验拓扑 图 1 1 注 xff1a 如无特别说明 xff0c 描述中的 R1 或 SW1 对应拓扑中设备名称末尾数字为 1 的设备 xff0c R2 或 SW2 对应拓扑中设备名称末尾数字为 2 的设备 xff0c 以此类推 xff1b
  • MapReduce实现二次排序

    默认情况下 xff0c Map输出的结果会按照key进行排序 xff0c 但在实际的应用中 xff0c 有时间我们不仅要对key进行排序 xff0c 同时还要对value进行排序 xff0c 这时候就要用到mapreduce中的二次排序 一
  • rosbag 从旧topic,迁移到新topic

    rosbag 从旧topic xff0c 迁移到新topic source 目标devel setup bash文件生成rules bmr迁移规则 rosbag check in bag g rules bmr修改迁移规则文件rules b
  • 研究生阅读文献技巧

    研究生如何做文献阅读和阅读笔记 以后大部分内容综合自PPT 研究生如何做文献阅读和阅读笔记 和 How to Read Paper 若侵权删 首先是一位研究生老师的建议 xff1a 今后大家提交的论文阅读笔记和工作报告尽量用英文写 可以直接
  • asp.net中执行exe应用程序

    在asp net中执行应用程序有两种方法 xff1a 1 调用win32函数ShellExecute 2 用 NET Framework中的Process类 下面我分别用这两种方法执行Windows中的记事本程序notepad exe 新建
  • Win10 安装Tensorflow-GPU版教程(附CUDA安装 could not fine compatible graphic hardware问题解答)

    入了深度学习的坑 xff0c 需要搭建Tensorflow环境 xff0c 虽然渣渣显卡 xff0c 但是总比CPU来得快 xff0c 果断选择GPU版 在网上找了很多资料 xff0c 受益颇多 但是由于tensorflow最近更新了 xf
  • 带你了解无人机的大脑-飞控

    无人机大脑 xff1a 飞控 无人机之所以能够在空中自主飞行就是因为无人机也和人一样 xff0c 也拥有一个大脑 xff0c 究竟是什么样的一个大脑才能够控制一架飞机在空中自动驾驶呢 xff1f 一起来看看 通俗点说 xff0c 能够自主起
  • STM32F103串口(ISP)下载

    1 ISP简介 ISP Iin System Programming 在系统可编程 xff0c 指电路板上的空白器件可以编程写入最终用户代码 xff0c 而不需要从电路板上取下器件 xff0c 已经编程的器件也可以用SP方式擦除或再编程 I
  • 用Docker搭建更酷的本地开发环境

    以前要在本地跑一些有意思的工程和实验 xff0c 都需要通过在本地装上一大堆软件来实现 最近发现有一种更酷的方式 xff1a Docker 用Docker在本地搭建开发环境有一系列显而易见的优势 xff1a 不用依赖公司的资源 xff0c
  • 只需修改一个像素,让神经网络连猫都认不出 | 论文+代码

    夏乙 编译整理 量子位 出品 公众号 QbitAI 想骗过神经网络 xff0c 让它认错图像 xff0c 需要对图像做多少修改 xff1f 一个像素就够了 一项来自日本的研究表明 xff0c 改动图片上的一个像素 xff0c 就能让神经网络
  • 小米迎来NLP首席科学家王斌:中科院研究员,雷军崔宝秋亲学弟

    雷刚 发自 凹非寺 量子位 报道 公众号 QbitAI 曾经武大郎 xff0c 今日小米科学家 小米又有AI科学家加盟 xff0c 这次是中国科学院信息工程研究所研究员王斌 xff0c 他将出任小米AI实验室NLP首席科学家 xff0c 负
  • IGMPv1,v2,v3详解

    简介 IGMP IGMP Internet Group Management Protocol xff09 作为因特网组管理协议 xff0c 是TCP IP协议族中负责IP组播成员管理的协议 xff0c 它用来在IP主机和与其直接相邻的组播
  • 华为最强AI芯片麒麟980发布:全球首款7nm手机芯片,双核NPU,6项世界第一

    安妮 雷刚 发自 凹非寺 量子位 报道 公众号 QbitAI 遥遥领先 xff01 这是华为消费者业务CEO余承东放下的狠话 xff0c 他说自家即将推出的手机芯片麒麟980 xff0c 将在全球范围内遥遥领先 而且领先的不是别家 xff0
  • Haar小波提升算法

    传统的小波变换是在傅里叶变换的基础上演变而来 xff0c 计算过程中存在着大量的卷积运算或是乘累加的计算 xff0c 如若在硬件上实现 xff0c 势必会消耗大量的寄存器资源 xff0c 而且速度也上不去 提升小波又称为第二代小波 xff0
  • 【Docker学习】Docker Hub + GitHub实现镜像自动构建

    近期学习Docker的相关知识 xff0c 尝试了一下Docker Hub 43 GitHub自动构建镜像 xff0c 在此记录一下过程 将GitHub账号关联到Docker Hub账号 设置位置 下滑到Linked Accounts xf

随机推荐

  • spring整合mybatis报错Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容

    在spring的配置文件中配置mybatis时使用的是 xff1a span class hljs comment lt 控制和MyBatis整合 gt span span class hljs tag lt span class hljs
  • linux中UDP编程

    在前面的文件中 xff0c 我们介绍了linux网络编程中与IP相关的知识和常用的函数总结 xff0c 本文针对具体的UDP通信 xff0c 来详细的介绍UDP通信的使用 xff0c 包括UDP通信中的点对点通信 xff0c 多播 xff0
  • 语音增强--卡尔曼滤波介绍及MATLAB实现

    语音增强 卡尔曼滤波 状态方程 x k 43 1 61
  • 树莓派官方系统(raspbian)安装及使用教程

    以下内容为本人原创 xff0c 欢迎大家观看学习 xff0c 禁止用于商业用途 xff0c 作者 xff1a 64 Yhen 原文网站 xff1a CSDN 原文链接 xff1a https blog csdn net Yhen1 arti
  • 主键和外键的区别

    一 什么是主键 外键 主键 xff1a 关系型数据库中的一条记录中有若干个属性 xff0c 若其中某一个属性组 注意是组 能唯一标识一条记录 xff0c 该属性组就可以成为一个主键 比如 1 学生表 学号 xff0c 姓名 xff0c 性别
  • C++中,使用libCurl实现http的post请求

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • nodejs版本管理NVM

    nodejs版本管理NVM NVM全称 xff08 Node Version Manager xff09 是一个用来管理node版本的工具 因为在开发electron版本应用时遇到了 xff0c nodejs使用版本冲突 xff0c 所以我
  • OSPF中DR、BDR竞选机制【转载】

    OSPF DR BDR 竞选机制详解 OSPF 上篇技术文章中提到了建立邻居和邻接关系 xff0c 而邻居关系建立成功之后 xff0c 在broadcast NBMA网络上会进行DR BDR竞选 DR产生背景 在MA网络中 xff0c 任意
  • Citrix Receiver在linux系统(Ubuntu)下的安装使用

    本文为解决在linux系统下Citrix Receiver安装完成后无法登录服务器的情况 xff0c windows下没有这个问题 其中报错为无法识别安全证书 提示 xff1a no such file or directory verif
  • ORA-28000:the account is locked错误解决

    Oracle数据库日志中出现ORA 28000 the account is locked的错误 xff0c 可以按下面的步骤处理 xff1a 1 查询FAILED LOGIN ATTEMPTS参数默认值 xff0c 这个参数限制了从第一次
  • 在Ubuntu上安装boost库

    boost中 xff0c 用到了别的函数库 xff0c 所以为了使用boost中相应的功能 xff0c 需要先安装系统中可能缺失的库 apt get install mpi default dev 安装mpi库 apt get instal
  • 嵌入式平台算法优化

    嵌入式平台算法优化 目录 目录 前言 4 1 嵌入式系统优化流程 6 1 xff0c 选用更优的算法 6 2 xff0c 选择嵌入式平台型号 6 3 xff0c 算法优化一般流程 9 2 高效的编程 15 1 xff0c 数据类型 15 2
  • [028] Gazebo构建Kinect模型,在RVIZ中显示点云PointCloud2出错:点云位姿错误,浮在空中

    一 Bug描述 1 发生错误的 urdf代码 xff08 也不是代码错误 xff0c 是gazebo的bug xff09 lt link name 61 34 camera link 34 gt lt visual gt lt origin
  • Win10校园网宽带连接频繁秒断

    问题 xff1a 宽带连接连上过后很快就断开 解决方法 xff1a 1 Win 43 R输入regedit打开注册表编辑器 2 打开路径 xff1a 计算机 HKEY LOCAL MACHINE SYSTEM ControlSet001 S
  • UML类图--泛化关系

    泛化关系 Generalization 属于类的继承关系 xff0c 表明了子类如何特化或实现父类的属性和方法 UML类图表示 xff1a 箭头指向 xff1a 带箭头的实线 xff0c 箭头指向父类 代码实现 xff1a 测试类 publ
  • 汉诺塔问题解析(C语言)

    目录 一 什么是汉诺塔问题二 汉诺塔移动图解三 代码实现总结 一 什么是汉诺塔问题 汉诺塔问题是一个经典的问题 汉诺塔 xff08 Hanoi Tower xff09 xff0c 又称河内塔 xff0c 源于印度一个古老传说 大梵天创造世界
  • Shell脚本学习——字符串处理

    最近在做很多的字符串处理的工作 xff0c 主要用的还是excel xff0c 但是很费神 xff0c 总是Ctrl 43 C和Ctrl 43 V 就想用shell脚本对对应的字符串进行批量处理 1 xff09 首先是读取文件中的每一行字符
  • DSP算法移植---总结

    总结 很久没有写文章了 xff0c 今天逛了逛博客 xff0c 看到DSP算法移植的文章 xff0c 至于这个项目 xff0c 本人解释下 本人7月份将硕士毕业了 xff0c 不久就要离开校园了 xff0c 所以我基本上不接触这个项目了 x
  • L2TP协议【转载】

    L2TP协议 一 43 L2TP Layer 2 Tunnel Protocol 第2层隧道协议 xff0c 是为在用户和企业的服务器之间透明传输PPP报文而设置的隧道协议 43 特性 灵活的身份验证机制以及高度的安全性 多协议传输 支持R
  • ROMFS文件系统分析

    ROMFS文件系统分析 ROMFS是一种简单的只读文件系统 xff0c 主要是用来当做初始文件系统来使用的 xff0c 在嵌入式linux或是uclinux中通常使用这中文件系统来作为引导系统的文件系统 xff0c 甚至uclinux有时就