162010,31(1)计算机工程与设计Computer Engineering and Design
0引言
NVRAM (non-volatile random access memory ,非易失性随机访问存储器)是广泛应用于网络路由器的一种存储器件。它如同PC 上的CMOS ,作用是存放路由器的配置参数。目前常见的NVRAM ,大都是静态SRAM ,即带有备用电源的SRAM ,它的实现最简单,同普通内存操作一样。但是在实际应用中,不是所有的开发板都配备有静态SRAM 。在这种情况下,如果使用该方案开发网络路由器,重新加入配备电源的SRAM 必须要重新排版,布线。开发周期与开发成本将会大大增加。因此,可以考虑在现有的硬件资源基础上,通过新的方式来实现NVRAM [1]。
本文就是以神州龙芯开发的CQ8401开发板为硬件平台,在自行裁剪和移植的嵌入式Linux 平台下,利用Nor Flash 来实现网络路由器的NVRAM 功能。
1NVRAM 新的实现方案分析
由于NVRAM 仅用于保存启动配置文件(Startup-Config ),
故其容量较小,通常在路由器上只配置32KB~128KB 大小的NVRAM 。配备电源的SRAM 速度较快,是目前读写最快的存储设备,而成本也比较高。一般的开发板所配备的Nor Flash
空间足够大,在系统性能得到满足的前提下,可以把Nor Flash 分出一个区来当作NVRAM 使用。SRAM 和Nor Flash 的对比分析,如表1所示。
网络路由器中的NVRAM 用于存放配置参数。正常启动路由器后,NVRAM 中的内容会拷贝到内存一份,我们对路由器的设置实际上就是修改内存中的参数。所以内存和NVRAM 中的内容可以不一样,直到使用write memory 将内存设置保存到NVRAM 。在系统起来以后,我们可以根据需要修改配备参
收稿日期:2009-07-17;修订日期:2009-09-18。
嵌入式系统工程
徐立松,郭晓金:嵌入式Linux 中NVRAM 的实现方案及驱动设计
2010,31(1)17
数,设定好所有参数或者退出系统时执行信息回写,把数据从内存拷贝回NVRAM 。
因此,Nor Flash 读写数据慢的缺点可以规避。在把Nor Flash 作为NVRAM 使用时,不宜过多访问Nor Flash ,对于通用的NVRAM 操作我们可以做下简化。不对一个的变量单独做调用和修改,而对整体做读写操作,本文将重点讲述NVRAM 呈现层设计。下面先看一下系统所应用的硬件平台。
2CQ8401开发板与Nor Flash
开发板以神州龙芯科技有限公司的嵌入式SOC -CQ8401为核心处理器,采用子母板方式,方便调试与扩展,支持32位通用PCI 总线设备扩展接口,板载16MB Nor Flash 。Nor Flash 的硬件原理图如图1所示。
Nor Flash 型号为INTEL 28F128J3D-75,16MB (8M ×16Bit ),片选为CS0。电阻R26接地(写保护使能)。Nor Flash 片选地址为0x00000000,系统启动引导程序BOOTLOAD 就装在Nor Flash 中。Nor Flash 的寻址范围为0x00000000-0x01000000,本系统取NVRAM 大小为128K ,因此把Nor Flash 中地址空间0x00ff0000-0x01000000的分区用做NVRAM 。
3驱动程序开发
任何一个计算机系统的运行都是系统中软硬件协作的结
果,设备驱动充当了硬件和应用软件之间的纽带,它使得应用软件只需要调用系统软件的应用编程接
口(API )就可让硬件去完成要求的工作。Linux 系统的设备驱动是内核的最重要的组成部分,其代码一般占内核代码的50%以上。
对于开发驱动程序来说,首先要明白硬件的工作原理与系统接口。本文所设计的NVRAM 驱动是使用Nor Flash 的一个分区,因此,首先要清楚Nor Flash 的工作原理。
3.1Nor Flash 工作原理
Nor Flash 和CPU 的接口属于典型的类SRAM 接口(如图
2所示),不需要增加额外的控制电路。
Nor Flash 的编程原理是只能将1写为0,而不能将0写为1。所以在Flash 编程之前,必须将对应的块擦除,而擦除的过程就是把所有位都写为1的过程,块内所有字节都变为0xFF 。擦除NOR FLASH 器件时是以64~128KB 的块进行的。INTEL 28F128J3D-75每个sector 是128K 。
3.2NVRAM 驱动设计
本文所设计的NVRAM 驱动是利用Nor Flash 的分区。对
于嵌入式系统来说,Nor Flash 驱动其实有两个,一个是在系统引导程序BOOTLOAD 中(Nor Flash 最重要的作用就是存储
BOOTLOAD ),当Linux 系统启动后,要重新加载Linux 下的Nor Flash 驱动。
Linux 系统中,提供了MTD (内存技术设备)系统来建立Flash 针对Linux 的统一、抽象的接口。在引入MTD 后,Linux 系统中的Flash 设备驱动及接口可分为4层,从上到下依次是;设备节点、MTD 设备层、MTD 原始设备层和硬件驱动层,如图3所示。
底层Flash 驱动直接与MTD 原始设备层交互,利用其提供的接口注册设备和分区[1-2]。本文的NVRAM 驱动设计,可采用两种方案:
(1)利用MTD 分区,直接划分给NVRAM ,操作如同Nor
Flash 通常操作,优点是设计简单,只需修改分区表,即可。但是效率较低。
(2)从底层Flash 硬件驱动截一分支出来,单独做NVRAM 驱动,定义接口。
Nor Flash 的读写访问效率本身就低于SRAM ,考虑到系统运行效率,本文采用第2种方案。
TE28F 128J3D-75Nor Flash 容量是16M ,NVRAM 所需空间比较小,128K 的容量足以满足要求。为了节省FLASH 空间,可以从底
端分出128K ,用做NVRAM 。重新划分的分区表如下所示:
static struct mtd_partition static_partitions []=
{
{.name ="BootLoader",
.size =
0x040000,.offset =0x0},//bootloader 存放的
区域
{.name ="Kernel",.size =0x0100000,
.offset =0x40000},//内核映像存放的区域
图1Nor Flash 硬件结构
TE28F128J3D-75
VPEN
VCCQ VCC2
VCC1
A24A23A22A21A20A19A18A17A16A15A14A13A12A11A10A9A8A7A6A5A4A3A2A1A0
RP#BYTE#STS GND3GND2GND1OE#WE#
CE2CE1CE0
DQ15DQ14DQ13DQ12DQ11DQ10DQ9DQ8DQ7DQ6DQ5DQ4DQ3DQ2DQ1DQ0
52504745413936345149464440383533
D15D14D13D12D11D10D9D8D7D6D5D4D3D2D1D0
292145455163153484221RP#BYTE#RD#
WE#CS0#R22R23010k
RSTOUT#+3.3V
R2510k NC
+3.3V
10k
R24
15
43379R260NC
R26connect:Write Protection
+3.3V
+3.3V R2110k
5630134567810111213171819202223242526272832
MA24
MA23MA22MA21MA20MA19MA18MA17MA16MA15MA14MA13MA12MA11MA10MA9MA8MA7MA6MA5MA4MA3MA2MA1MA0U6
NOR
Flash
182010,31(1)
计算机工程与设计Computer Engineering and Design
{.name ="RamDisk",.size =0x400000,
.offset =
0x140000},//ramdisk 存放的区域{.name="cramfs (2MB )",.size=0x200000,.offset=0x540000},//只读的cramfs 区域
{.name="jffs2(0.75MB )",.size=0xc0000,.offset=
0x740000},//可读写的jffs2区域
{.name="nvram (128KB )",.size=0x20000,.offset=
0xff0000}//NVRAM 区域
};
驱动程序是应用软件访问硬件的桥梁,对于本系统的NVRAM 来说,它在应用层所提供的功能是保存路由器的配置参数,支持修改参数,和显示参数。
Nor Flash 中对特定变量的存取,采取的方法是设置环境变量,可以读取、修改任意变量。在路由器系统启动以后,我们对NVRAM 的操作其实是对内存数据的操作,直到执行write back 才会把内存的数据拷贝回NVRAM 。
哈希表是一种高效的存取特定变量的结构,本文的NVRAM 应用层使用哈希表存储路由器信息。它所用到的命令包括:显示变量值(nvram show );修改变量值(nvram config );写回(write back )。
底层驱动需要给应用层提供相应的接口函数。Linux 系统设备驱动程序的接口函数,通过file_operation 结构体来访问。file_operations 变量会在驱动程序初始化时,注册到系统内部。当操作系统对设备进行操作时,会调用驱动程序注册的file_operations 结构中的函数指针[3]。
应用层程序调用驱动程序接口可以通过命令访问的形式,即通过ioctrl 函数。为了方便操作和对驱动进行精简,本文的NVRAM 驱动把read 、write 、llseek 操作集成到ioctrl 函数中,通过命令供应用程序调用。NVRAM 的file_operations 结构如下:
Static struct file_operations nvram_fops ={.owner =THIS_MODULE,.open =open_nvram,.release =release_nvram,
.ioctrl =ioctrl_nvram
}
.owner =THIS_MODULE 不是一个操作,它是一个指向拥有这个结构模块的指针。这个成员用来在操作还在被使用时阻止模块被卸载。几乎所有时间中,它被简化为THIS_MOD-ULE ,一个在<linux/module.h>中定义的宏,此项是必须的。
.open =open_nvram 和.release =release_nvram 打开关闭设备操作。.ioctrl =ioctrl_nvram 包括了应用层对NVRAM 的所有操作的调用函数。
static int ioctrl_nvram (struct inode *node,struct
file *filp,unsigned int cmd,unsigned long arg ){
switch (cmd ){char *strp;
case NVRAM_SHOW:
//nvram_read 函数封装了对flash 特定区域的读取操作
strp =nvram_read ();…
case NVRAM_WR_BACK:
//擦除flash 中的0x00ff0000-0x01000000扇区
sector_erase ();//将内存中的哈希表写回flash
write_nvram (filp,arg );
…}}
3.3驱动程序的注册
驱动程序的入口不同与应用程序的main ()函数,它是通
过init_module ()函数来实现,NVRAM 驱动中的init_module ()函数如下:
unsigned int nvram_major =0;
int init_module (void ){int result;
result =register_chrdev (0,"NVRAM",&nvram_fops );if (result <0){
printk (KERN_INFO "NVRAM:can't get major number\n");return result;}
if (nvram_major ==0)nvram_major =result;/*dynamic */return 0;
}
init_module 做了一件事,就是向系统的字符设备表登记了一个字符设备。register_chrdev 需要3个参数,参数一是希望获得的设备号,如果是零的话,系统将选择一个没有被占用的设备号返回。参数二是设备文件名,参数三用来登记驱动程序实际执行操作的函数的指针。
同样在驱动程序注销的时候调用cleanup_module ()函数。void cleanup_module (void ){
unregister_chrdev (test_major ,"test");
}驱动程序成功注册后,应用程序通过命令来调用NVRAM 驱动程序函数,实现具体的操作。
3.4驱动程序的实现
嵌入式Linux 中,驱动程序的编译添加分为动态加载和静
(下转第129页)
图3Linux MTD 系统结构
根文件系统
文件系统字符设备节点MTD 字符设备
MTD 块设备
块设备节点MTD 原始设备
Flash 硬件驱动
王晓亮:基于Yices 对时间自动机的有界模型检测
2010,31(1)129
ficiently [C ].Formal Methods in System Design,2005:267-292.[3]
Junhao Shi,G
ller,Henrik Hulgaard,Henrik Reif Andersen.Symbolic
model checking of timed guarded commands using difference decision diagrams [J ].Journal of Logic and Algebraic Program-ming,2002,52-52:53-77.[6]
Scott Cotton,Andreas Podelski,Bernd Finkbeiner.Satisfiability checking with difference constraints [D ].Saarbruceken:IMPRS Computer Science,2005.[7]
Farn Wang.Symbolic parametric safety analysis of linear hybrid
systems with BDD-like data-structures [C ].IEEE Trans Softw Eng,2004:38-51.
[8]
Clark Barrett,Leonardo Moura,Aaron Stump.Design and results of the first satisfiability modulo theori
es competition (SMT-COMP 2005)[J ].Journal of Automated Reasoning,2005,35(4):373-390.
[9]Daniel Le Berre,Laurent Simon.The essentials of the SAT 2003competition [C ].Proceedings of the Sixth International Confe-rence on Theory and Applications of Satisfiability Testing,2003:452-467.linux内核设计与实现 pdf
[10]Gerd Behrmann,Alexandre David,Kim G.Larsen.A tutorial on
uppaal [C ].Proceedings of the 4th International School on For-mal Methods for the Design of Computer,Communication,and Software Systems,LNCS 3185,2004.
态加载两种方式。动态加载就是把驱动程序编译成模块,在系统运行时加载;静态加载就是把驱动程序编译进内核,通过运行内核加载。调试程序中,一般使用动态加载,来增加效率。网络路由器中采用的是静态加载方式。
在driver/char 目录下新建nvram 目录,把nvram 驱动放到此目录下,并编写makefile ,然后在该目录的Kconfig 文件中包含nvram 配置项目。
config cq8401_nvram bool “cq8401nvram driver ”depends on ARCH_CQ8401help …
编译内核时在相应菜单中选上此项(选项为Y ),编译内核时就会执行该驱动的编译。CQ8401采用mips
架构,可以使用mipsle-linux-gcc 工具编译。编译好的内核烧写到开发板中,启动系统,NVRAM 驱动便可以正常使用了。应用程序就可以通过调用驱动提供的接口,来访问和操作硬件,实现NVRAM 的功能[3-6]。
4NVRAM 功能验证与测试
系统运行以后我们通过调用NVRAM 程序,执行命令来测试NVRAM 驱动。NVRAM 读写正常,操作方便。操作命令nvram show 的显示结果的部分截图如图4所示。
从图中可以看出,NVRAM 显示了网络路由器的配置信息,结果完全正确[7-9]。
5结束语
本文阐述了在嵌入式Linux 下,NVRAM 的一种新的实现
方式以及其驱动的开发过程。Linux 驱动是嵌入式Linux 系统
开发的重点问题,也是难点问题。它具有特定的DDI (设备驱动接口)接口,以及系统调度方法。这些也是驱动程序所关心的问题。
本文根据NVRAM 的特点,以及Linux 驱动程序的架构,设计了一套实际可行且精简的操作接口。应用程序通过系统函数接口调用驱动程序,操作简单。驱动程序可移植性与可修改性良好,满足了网络路由器对它的需求。目前该方案已经成功运用与该路由器,效果良好。
参考文献:
[1]宋宝华.Linux 设备驱动开发详解[M ].北京:人民邮电出版社,2008.
[2]Christian Benvenuti.Understanding Linux networking internals [M ].O'Rreilly &Associates,2006.
[3]Rubini A.Linux 设备驱动程序[M ].北京:中国电力出版社,2000.
[4]孙琼.嵌入式Linux 应用程序开发详解[M ].北京:人民邮电出版社,2007.
[5]袁丽慧,彭磊.可重用Linux 设备驱动程序框架[J ].计算机工程,2008,34(10):89-91.
[6]马修,斯通斯.Linux 程序设计[M ].北京:人民邮电出版社,2007.[7]朱斌,程明霄.嵌入式Linux 的PC104数据采集卡的驱动设计[J ].计算机工程,2008,34(21):236-238.
[8]王辉,王自强.LIRC 设备驱动程序的设计和实现[J ].微处理机,2008(2):165-167.
[9]
何亚军,邓飞其.嵌入式Linux 中I2C 总线驱动程序设计[J ].计算机工程与设计,2008,29(10)
:2517-2519.
图4NVRAM 演示
(上接第18页)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。