一、补充文件系统知识
Linux根文件系统是存放tool软件、lib文件、script(脚本)、配置文件、其他特殊文件、自己开发的应用程序的地方。嵌入式linux的根文件系统rootfs就像windows操作系统的C、D盘这种概念机制,FLASH对应硬盘。但linux是挂载点的概念,根文件系统是一个整体,组织到一个树状的目录结构中。这种文件组织遵守文件系统科学分类标准FHS,一种国际标准。运行、维护系统所必须的各种
在开发、测试阶段,基本上都是使用NFS(网络文件系统),NFS文件系统是在你的开发主机HOST里,不是在你的板子里。制作嵌入式产品根文件系统,就是要把NFS指向的文件系统文件夹里所有的内容,通过其他少数几种的Linux文件系统打包生产一个2进制镜像文件,然后以某种方式烧写到FLASH芯片内。开发阶段,特别是应用程序开发、动态加载的驱动模块开发,使用NFS,可以省去麻烦的根文件系统镜像文件的下载和烧写过程,便可以在自己板子上运行这些开发的程序和模块。
 
Linux支持超过50种文件系统,但是只有少数几种在嵌入式OS中常用,见下图。linux嵌入式产品的根文件系统是需要烧写到Flash芯片里。
 

Cramfs文件系统:(Compressed ROM File System)是个简单,压缩的,只读的文件系统。除了可以用于MTD下只读并且极少更新img的NOR/NAND,IDE的CF,FTL/NFTL的NOR/NAND,可作为RAM disk的IMG存储。由于简单,Cramfs有一些限制,例如最大支持16M(?256M),没有当前(.)和父(..)目录,页大小固定为4096,gid(8位)最大为255,所有的链接文件计数都是1等等。在cramfs文件系统中,每一页(4KB)被单独压缩,可以随机页访问,其压缩比高达2:1,为嵌入式系统节省大量的Flash存储空间,使系统可通过更低容量的FLASH存储相同的文件,从而降低系统成本。Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去运行,但这并不代表比Ramfs需求的RAM空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当我们读取的档案不在内存时,Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。另外,它的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性。由于以上特性,Cramfs在嵌入式系统中应用广泛。但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容对进扩充。
制作Cramfs根文件系统命令如下:
#mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile
mkcramfs的各个参数解释如下:
 -h:显示帮助信息
-e edition:设置生成的文件系统中的版本号
-i file:将一个文件映像插入这个文件系统之中(只能在Linux2.4.0以后的内核版本中使用)
-n name:设定cramfs文件系统的名字
dirname:指明需要被压缩的整个目录树
outfile:最终输出的文件
cramfsck的命令格式:
cramfsck [-hv] [-x dir] file
cramfsck的各个参数解释如下:
-h:显示帮助信息
-x dir:释放文件到dir所指出的目录中
-v:输出信息更加详细
file:希望测试的目标文件
例子:#mkcramfs rootfs rootfs.cramfs生成rootfs.cramfs文件系统镜像.其中rootfs是你调试的根文件系统的文件夹,rootfs.cramfs是生产镜像文件的名字。
Squashfs文件系统:是压缩的只读的fs,保留了Cramfs很多优点,去掉它的限制。压缩比更高。是一个不错的文件系统。命令为:#mksquashfs [source] [dest]
JFFS2文件系统:可写、保留数据、压缩、掉电保护,提供wear leveling,适合板载NOR、NAND和Doc。JFFS2提供垃圾回收机制,通常可以很好地工作。但是当文件系统接近极限或者要求更新一个非常大的文件,垃圾回收的时间会很长,将会延迟文件系统的操作,这会对没有考虑到这种情况的某些实时要求的软件带来负面的影响。当空间满的时候,尝试更新或者阶段文件内容会被提示文件系统已满并失败,即使看起来不要求添加存储block,这是因为日志结构文件系统,需要在log中增加log。在使用的时候,我们应保证存储空间的充足,上面的应用能够容忍时延(避免快满时候垃圾回收的消耗影响)。 JFFS2用途很广,但是对于现在容量巨大的闪存不适合,新的UBI文件系统出现。JFFS2的不可扩展性是最大的问题,作为JFFS2的升级,JFFS3支持大容量的闪存。JFFS2使用MTD工具:
#mkfs.jffs2 –r ottfs/ –o images/rootfs-jffs2.img –e 128kiB 其中128是指擦写block的大小,如果超过实际闪存的大小,会引起文件系统的崩溃,如果太小,block内有部分存储空间没能利用。
#sumtool –i rootfs-jffs2.img –o rootfs-jffs2-summed.img –e 128KiB 增减erase block的summary node。
 
YAFFS2文件系统:是可写,下电保护的文件系统,广泛引用于Linux和RTOSeS。和JFFS2相比,它减少一些功能,因此速度更快、占用内存资源更少。YAFFS2自带NAND芯片的驱动,是专门为NAND闪存设计的。以前的YAFFS只支持512-BYTE/Page的NAND,而YAFFS2不但兼容512-BYTE/Page,还支持目前流行的2048-BYTE/Page大容量NAND FLASH。YAFFS2文件系统的镜像工具是mkyaffs2img。随便在GOOGLE上输入mkyaffs2img就可以找到满屏幕的制作方法,这里不用介绍。
 
RAMFS文件系统:
讨论RAMFS,就不得不讨论RAM disk,在RAM中,而作为一个block设备,内核可以同时支持多个RAM disk。通常用于保存磁盘文件系统中压缩的img。这在嵌入式操作系统的初始化中使用,kernel可以从存储设备中提取initial RAM disk(initrd)img作为的他的根文件系统。一开始,kernel根据boot的参数是否表面intrid,如果是,他将从特定的存贮介质提取文件系统的img并放入RAM disk,同时mount为根文件系统。initrd的机制是以最简单的方式提供一个带根文件系统的内核在RAM中。对于新的系统,推荐使用Initramfs机制。
Tmpfs文件系统:也是RAM disk的一种,可以使用物理内存,是一个存放在虚拟memory的文件系统,不提供永久保存,适合于存储临时的数据,例如/tmp,用于Linux的page cache和dentry chache。
RAM disk的特点就是速度快,因为在RAM运行的。缺点就是每次重新启动系统时,前面的工作就无法保存。创建RAM Disk使用的命令式mke2fs。
有关嵌入式常用的文件系统详细介绍和制作命令、方法,大家可以在网上搜索得到。
 
二、TI davinci根文件系统target介绍
在mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le目录下,有个target的文件夹,这个就是TI EVM的根文件系统了。Target里的内容,见下图,本人是单独COPY出来到自己工作目录下,这点在《开发环境篇》有介绍。TI在这个target文件系统包里放置很多开发工具,其实就是一个开发应用程序的环境,你进到usr目录下就明白这点,里边包括交叉编译命令、很多头文件和应用程序的源代码、usr/lib里的lib文件,等等。其实这些东西肯定是不能全部烧到自己的板子里的。单单这个usr里相关的文件大小就达1G!!!因为TI EVM东西多,复杂,所以我们裁减的时候,最好做好备份。当然,有些朋友是自己手动重新制作根文件系统,再借助“Busybox”这个大名鼎鼎的嵌入式linux瑞士军刀,一个精简的文件系统就出来了。本人在S3C2440、2410的板子上玩过,挺不错的,非常精简。本文暂且不讨论这种方法。
 

三、TI davinci根文件系统target的裁减
进入自己工作的target文件夹里,见上图:
bin文件夹:里边主要是一些linux shell命令,所有用户都可以使用的、基本的命令,都是很基本的东西,暂时不用动它,保留。
boot文件夹:是存放编译内核的一些相关文件,比如uImage等,这些东西没必要放到板子上的文件系统里,删除掉。
dev文件夹:存放非常多的设备节点,如果你对这些节点不是很熟悉,分不清哪些是你系统用到的,哪些是不用的,可以保留,整个dev只有16~17k的大小。当然节点太多也不好。
 etc文件夹:存放很多启动的脚本文件、系统配置文件,这是下面移植要讨论的重点。整个文件夹有6~7M,像samba、apt这种在普通嵌入式产品不常用的东西可以删除掉。如果产品不是带LCD图像界面的产品,X11(X Window 系统版本 11,简称 X11,是一个对网络透明的客户/服务器架构的图形显示系统。它支持应用程序在你的屏幕上绘制象素,线条,文字,图象等等。 X11 还包括一些其它的辅助的函数库,使得它可以容易地绘制用户界面,例如:按钮,文本输入区等等)这个可以删除掉,单这个文件夹就有2.85M。
 home文件夹:空的文件夹,系统运行会用到,普通用户的主目录,一定要保留。
 lib文件夹:很多工具和应用程序使用的库文件,不是高高手,最好不要删掉里边的文件。
 media文件夹:空的文件夹,保留。
 mnt文件夹:空文件夹,以后使用U盘和SD卡时,会挂到该目录,所以保留。
 opt文件夹:空文件夹,自己开发的一些应用程序可以放到这里,比如TI evm的一些应用程序就放在/opt/dvsdk/dm6446/,存放encode,decode,encodedecode的应用程序,等等。
 proc文件夹:空的文件夹,系统运行会用到,proc文件系统的挂载点,保留。
 root文件夹:空的文件夹,系统运行会用到,root用户的主目录,一定要保留。
 sbin文件夹:存放很多工具和基本的系统命令,它们用于启动系统、修复系统,在嵌入式产品里,可以把不常用的mkfs.xx的文件全部去掉。其他有很多工具和命令,要根据你自己的产品,不用到的都删掉,裁减sbin建议再单独备份一下sbin,通过NFS,一边删除,一边测试,保证删除掉后你的产品还很好地工作。这是一种笨办法,毕竟要全部理解里边的每个命令和工具的作用也需要很多时间。建议这个文件夹最好不要动太多手脚。
 srv文件夹:空的文件夹,保留。
 sys文件夹:空的文件夹,系统运行会用到,比如sysfs,保留。
 tmp文件夹:空的文件夹,系统运行会用到,存放临时文件,保留。
 usr文件夹:上面提到,这个文件有很多在产品出厂不用到的东西,armv5tl-montavista-linux-gnueabi文件夹直接删除掉;bin文件夹里的arm_v5t_le-XXXXX和armv5tl-montavista-linux-gnueabi-XXX也去掉吧;include、local、share、src、X11R6文件夹全部去掉;Usr/lib/tcng/test干掉;然后根据自己产品的,像perl5、python2.4、X11等等,不用到就搞定它们。笨办法就是使用NFS和板子共同测试,这样下来usr就小多了。
var文件夹:存放可变的数据,var/cache/cracklib里的文件很大,不知在TI EVM有什么用,本人不用;var\lib\rpm里的文件本人也不用;var/www/html/manual是在开发html的时候用到,本人不用。这几个都是var里耗空间的文件夹。另外,在使用NFS调试的时候,var/log下的文件会保存每次内核启动的打印信息,测试多了,debug,kern.log,messages等文件也加大,所以制作时要注意这些文件的裁减。
    按照上面的动作下来,一个可以用的根文件系统也出来了,但还不是简洁高效的,有些东西还得根据自己的板子要支持的功能选择性保留和裁减。有些工具、命令、应用程序开始没用到,但是后来升级产品会用到,所以,裁减要有针对性和规划性。特别是有些产品使用小于等于64M NAND的嵌入式产品,要做的工作就更多,这里仅供学习和参考。
 
四、TI davinci根文件系统target的移植
1、系统的分区:
在linux-2.6.18移植的博客文章介绍了FLASH的分区,这里就不用重复了,一般分区是: Bootloader(UBL+U-BOOT)+参数 为mtdblock0,kernel为mtdblock1,根文件系统rootfs为mtdblock2。也有这样分的:Bootloader(UBL+U-BOOT) 为mtdblock0,参数为mtdblock1,kernel为mtdblock2,根文件系统为mtdblock3。Bootloader要从FLASH 加载根文件系统,比如jffs2的根文件系统,u-boot的bootargs应该是:mem=118M console=ttyS0,115200n8 rootfstype=jffs2 root=/dev/mtdblock2 noinitrd rw ip=off或者是其他类型的文件系统。同时,u-boot对根文件系统的烧写要支持,因为jffs2,cramfs,yaffs2等每种文件系统的烧写格式都不一样,烧写的地址一定要和内核的FLASH分区地址一一对应。(补充:在DVSDK2.0中,U-BOOT的参数mem=118M,不再是120M,因为TI DVSDK2.0 CODEC ENGINE要求分配给cmem的大小是10M)。
2、内核选择支持对应的文件系统
   通过make menuconfig的配置界面,你的板子要支持什么样的文件系统,是cramfs,Squashfs,jffs2还yaffs2,则要对对MTD等相关选项进行选择,见linux-2.6.18移植的博客。
   3、对根文件系统权限操作
Target下每个目录的权限不是全部一样的,根据自己的文件系统的类型,比如yaffs2,tmp、var等目录可以使用chmod –R 777 tmp , chmod –R 777 var命令设置,文件夹域的设置使用chown的命令。为什么要这样强调呢?也许很多人调试DAVINCI 板子会碰到:Starting OpenBSD Secure Shell server: sshd/var/empty/sshd must be owned by root and not group or world-writable. failed (255: ).这个就是根文件系统权限和域得设置有问题。
4etc目录下的移植
   A、拷贝你的LINUX开发主机etc目录下的passwd、group、shadow文件到etc目录下。这样目标板就使用和你LINUX主机一样的登录账号和密码了。如果passwd、group、shadow被破坏了,如何都进不去板子的shell命令行,而且你的产品没有严重网络安全要求,这里还有一个绝招:把target/etc 下的securetty文件改个名字,不用securetty就可以了,这样输入账号直接回车就可以了。
 
   B、etc目录下新建一个目录sysconfig,并新建文件HOSTNAME,内容为“你公司名字或你喜欢的名字”。同时在etc/init.d/下RcS文件最后面加入:/bin/hostname –F /etc/sysconfig/HOSTNAME,在profile最后面加入:
USER="`id -un`" (注意 ` 是键盘1旁边的 `
LOGNAME=$USER
PS1='[\u@\h \W]# '  (注意是键盘 ; 旁边的linux文件下显示不一样)
PATH=$PATH
HOSTNAME=`/bin/hostname` (注意 ` 是键盘1旁边的 `
export USER LOGNAME PS1 PATH
这样在板子上进入shell的命令行时,会显示“[root@你定义的名字~]#”的格式。
 
   C、etc/fstab文件修改:目前这个本人直接使用TI的,但是自己的产品有时会定义
sysfs              /sys         sysfs       noauto                          0 0
tmpfs             /dev/shm tmpfs      noauto                                 0 0
目前没有验证,如果哪个网友对这方面熟悉,可以在博客上讨论。
 
   D、流程介绍
      根文件系统挂接到VFS(linux虚拟文件系统,一种软件接口机制,原理这里不描述)成功后,会根据脚本和配置一步一步运行。我们可以通过以下流程去熟悉:
先看inittab
      次看init.d/rcS
然后etc/rc.d/rcS.d,rcS.x等文件,开机是启动/etc/rc.d/rcS.d/下的脚本,然后是/etc/rc.d/rc3.d/下的脚本。只需把用户的程序编译称shell脚本,放在rc3.d下面就可以了。
      S开头的脚本基本上是系统运行初始化要做的工作,K开头就是关机要做的工作。
     客户如果要在开机运行自己的某些应用程序,也可以修改etc/init.d/rcS,在
for i in /etc/rc.d/rcS.d/S??*
do
           # Ignore dangling symlinks for now.
           [ ! -f "$i" ] && continue
           case "$i" in
                 *.sh)
                      # Source shell script for speed.
                      (
                          trap - INT QUIT TSTP
                          set start
                          . $i
                      )
                      ;;
               *)
                     # No sh extension, so fork subprocess.
                     $i start
                     ;;
            esac
done
在这后面加自己的运行命令就可以了。
 
   E、制作根文件系统映像文件
      就是使用mkcramfs、mkyaffs2image这些命令对整个修改的target文件进行镜像打包了,格式上面已经介绍了。
 
五、点评
以上是本人的经验之谈,肯定有描述不足的地方,希望网友能在博客里指出来,大家一起学习。到目前为止,有关DM6446开发攻略的主架构的文章,基本上接近尾声,最后1篇,有关自己开发的GPIO驱动移植的文章,近期也会出来。以后要写也是某个环节的补充。其实写这些文章,就是希望有这方面的开发高手过来点评一下,指出不足和错误的地方。毕竟本人在这方面还有很多东西要学习。

TI Davinci DM6446开发攻略——根文件系统的裁剪和移植的更多相关文章

  1. Davinci DM6446开发攻略——LINUX GPIO驱动源码移植

    一.             DM6446 GPIO的介绍      说到LINUX 驱动移植,没有移植过的朋友,或刚刚进入LINUX领域的朋友,最好去看看<LINUX 设备驱动程序>第三 ...

  2. TI Davinci DM6446开发攻略——开发环境搭建

    TI DAVINCI DM6446的开发环境搭建不像三星S3C2410,S3C2440,ATMEL的AT91SAM9260之类的单核ARM那么简单,因为DM6446还有DSP端的开发环境,以及双核之间 ...

  3. TI Davinci DM6446开发攻略——UBL移植

     UBL的程序设计,相对UBOOT.KERNEL.ROOTFS.设备驱动.DSP开发来说,还是比较简单.我们先从DAVINCI的启动说起,了解UBL在DAVIN系统中的位置和作用.对于固件程序烧写在N ...

  4. Davinci DM6446开发攻略-UBOOT-2009.03移植2 nand flash的烧写

      很长一段时间没有更新博客了,是因为要推出新开发方案和做好客户服务工作,忙得不易乐乎.有关DAVINCI U-BOOT的移植,以前写过一篇u-boot-1.3.4(2008年的),其实和这个u-bo ...

  5. Davinci DM6446开发攻略——u-boot-1.3.4移植(1)

    UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2,而TI最新的EVM开发包里的UBOOT是1.2.0版本,国内很多公司还一直使用u-boot-1.1.4和 ...

  6. Davinci DM6446开发攻略——linux-2.6.18移植

     TI DAVINCI 使用最新的内核是montavista linux-2.6.18,之前说过,国内很多公司,包括开发板的软件包,一直在使用montavista linux-2.6.10,这个版本准 ...

  7. Davinci DM6446开发攻略——DSP开发工程建立

    前段时间一直忙一个项目,同时在生活上时时提防和抵抗中国地沟油.国外核心转基因调和油.大豆油.色拉油.大米玉米.可怕的喂药鱼.药水泡农药喷无虫咬的青菜,所以没时间打理自己的博客,让开发攻略停顿了一段时间 ...

  8. DAVINCI DM6446 开发攻略——V4L2视频驱动和应用分析

     针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavista linux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavis ...

  9. DM6446开发攻略——u-boot-1.3.4移植(1)

    http://zjbintsystem.blog.51cto.com/964211/282387转载   UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2 ...

随机推荐

  1. 小白的.Net Core 2.0 ConsoleApp入门(keng)指南(一)

    一.准备工作 准备工作很简单,甚至可以不用Visual Studio,一只.NET CORE和Runtime即可(你有考虑过世界第一IDE的感受吗) 下载:https://www.microsoft. ...

  2. vhost-user 简介

    什么是 vhost-user 在 vhost 的方案中,由于 vhost 实现在内核中,guest 与 vhost 的通信,相较于原生的 virtio 方式性能上有了一定程度的提升,从 guest 到 ...

  3. c#基础(一)

    一. C#与.Net的关系 C#是一种相当新的编程语言.C#的重要性体现在以下两个方法: 1).它是专门为Microsoft的.net FrameWork一起使用而设计的 (.net FrameWor ...

  4. 话说CentOS6的启动流程

    1.按下开机按钮,电脑的主板通电,电脑开始加电自检(POST,Power On and Self Test),测试主机的硬件是否满足开机的要求. 2.加载主板上的BIOS(Base Input/Out ...

  5. 从UUID想到的

    1.UUID的定义 通用唯一标识符(UUID)被设计成一个在时间和空间上都独一无二的数字,常被用作唯一性标识. UUID是一个由5位十六进制数的字符串表示的128比特数字,其格式为 aaaaaaaa- ...

  6. BZOJ 4538: [Hnoi2016]网络 [整体二分]

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  7. 读书共享 Primer Plus C-part 4

    第四章 字符串和格式化输入输出 关于printf -  左对齐 #include<stdio.h> void main() { char str [100] = "liuchua ...

  8. jquary 单选,多选,select 获取和设置值 jquary自定义函数

    <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" ...

  9. location对象浅探

  10. PHP基础点滴

    PHP基础点滴 双冒号::的用法: 双冒号操作符即作用域限定操作符Scope Resolution Operator可以访问静态.const和类中重写的属性与方法. 伪类型(pseudo-types) ...