2008年7月29日星期二

wince学习 wince5.0下EP9315串口驱动结构,移植到AT91SAM9263下的方法

EP9315内部串口驱动结构:
EP9315内部串口采用分层的驱动结构。
对内核层的接口函数,在
E:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\SERIAL文件夹中的Mdd.c文件中。
他的目的是建立驱动的结构,
COM_Init
COM_Deinit
COM_Open
COM_Close
COM_Read
COM_Write
COM_Seek
COM_PowerDown
COM_PowerUp
COM_IOControl
其中还有中断的处理进程。
然后一层是最底层的硬件操作层
COM层函数通过一个结构体调用这一层函数。
在E:\WINCE500\PLATFORM\Eac0921\Src\Drivers\Serial文件夹中的p1010com.c文件定义。
Const HW_VTBL IoVTbl = {
SerInit,
SL_PostInit,
SerDeinit,
SerOpen,
SerClose,
SL_GetInterruptType,
SL_RxIntr,
SL_TxIntrEx,
SL_ModemIntr,
SL_LineIntr,
SL_GetRxBufferSize,
SerPowerOff,
SerPowerOn,
SL_ClearDTR,
SL_SetDTR,
SL_ClearRTS,
SL_SetRTS,
SerEnableIR,
SerDisableIR,
SL_ClearBreak,
SL_SetBreak,
SL_XmitComChar,
SL_GetStatus,
SL_Reset,
SL_GetModemStatus,
SerGetCommProperties,
SL_PurgeComm,
SL_SetDCB,
SL_SetCommTimeouts,
};
调用方法如下:
PHWOBJ GetSerialObject(DWORD DeviceArrayIndex)
{
PHWOBJ pSerObj;
// Unlike many other serial samples, we do not have a statically allocated
// array of HWObjs. Instead, we allocate a new HWObj for each instance
// of the driver. The MDD will always call GetSerialObj/HWInit/HWDeinit in
// that order, so we can do the alloc here and do any subsequent free in
// HWDeInit.
// Allocate space for the HWOBJ.
pSerObj = (PHWOBJ)LocalAlloc( LMEM_ZEROINITLMEM_FIXED ,sizeof(HWOBJ) );
if ( !pSerObj )
return (NULL);
// Fill in the HWObj structure that we just allocated.
pSerObj->BindFlags = THREAD_AT_OPEN; // Have MDD create thread when device is first opened.
pSerObj->dwIntID = 0; // SysIntr is filled in at init time
pSerObj->pFuncTbl = (HW_VTBL *) &IoVTbl; // Return pointer to appropriate functions
// Now return this structure to the MDD.
return (pSerObj);
}
其中的SL开头的函数都是在p1010ser.c文件中定义。


EP9315外扩串口的驱动结构。
EP9315外部串口也采用分层的驱动结构。不同的是EP9315外扩串口将所有的代码都在
E:\WINCE500\PLATFORM\Eac0921\Src\Drivers\Ext_uart文件夹中。
其驱动结构如下:
对内核层的接口函数,在Mdd.c文件中。
COM_Init
COM_Deinit
COM_Open
COM_Close
COM_Read
COM_Write
COM_Seek
COM_PowerDown
COM_PowerUp
COM_IOControl
其中还有中断的处理进程。
然后一层是最底层的硬件操作层
COM层函数通过一个结构体调用这一层函数。
在CCSer_pdd.c文件中。
Const HW_VTBL SerIoVTbl= {
CCSerInit,
SL_PostInit,
CCSerDeinit,
CCSerOpen,
CCSerClose,
SL_GetInterruptType,
SL_RxIntr,
SL_TxIntrEx,
SL_ModemIntr,
SL_LineIntr,
SL_GetRxBufferSize,
CCSerPowerOff,
CCSerPowerOn,
SL_ClearDTR,
SL_SetDTR,
SL_ClearRTS,
SL_SetRTS,
CCSerEnableIR,
CCSerDisableIR,
SL_ClearBreak,
SL_SetBreak,
SL_XmitComChar,
SL_GetStatus,
SL_Reset,
SL_GetModemStatus,
CCSerGetCommProperties,
SL_PurgeComm,
SL_SetDCB,
SL_SetCommTimeouts,
SL_Ioctl
};
调用方法如下:
//HWOBJ for EXT_UART1 product serial
HWOBJ SerObj4 =
{
THREAD_AT_OPEN,
0,
(PHW_VTBL) &SerIoVTbl
};

//HWOBJ for EXT_UART2 product serial
HWOBJ SerObj5 =
{
THREAD_AT_OPEN,
0,
(PHW_VTBL) &SerIoVTbl
};

//HWOBJ for EXT_UART3 product serial
HWOBJ SerObj6 =
{
THREAD_AT_OPEN,
0,
(PHW_VTBL) &SerIoVTbl
};

//HWOBJ for EXT_UART4 product serial
HWOBJ SerObj7 =
{
THREAD_AT_OPEN,
0,
(PHW_VTBL) &SerIoVTbl
};

其中的SL开头的函数都是在Ser16550.c文件中定义。


扩展串口驱动从EP9315移植到AT92SAM9263下:
1、直接将驱动代码文件夹Ext_uart拷贝到AT92SAM9263的driver下。
2、修改Ext_uart文件夹中的sources文件
!if 0
Copyright (c) Microsoft Corporation. All rights reserved.
!endif
!if 0
Use of this source code is subject to the terms of the Microsoft end-user
license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
If you did not accept the terms of the EULA, you are not authorized to use
this source code. For a copy of the EULA, please see the LICENSE.RTF on your
install media.
!endif

!IF ("$(BSP_NOEXTSERIAL)" == "1") && ("$(BSP_BIN)" != "1")
SKIPBUILD=1
!ENDIF


RELEASETYPE=PLATFORM
TARGETNAME=at91sam9263ek_extserial
TARGETTYPE=DYNLINK
TARGETLIBS= \
$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \
$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\ceddk.lib \

SOURCELIBS= \
$(_PLATCOMMONLIB)\$(_CPUDEPPATH)\at91sam926x_serial.lib \

SOURCES= \
mdd.c \
ccser_pdd.c \
ser16550.c

DLLENTRY=DllMain
DEFFILE=at91sam9263ek_extserial.def
FILE_VIEW_RESOURCE_FOLDER= \
at91sam9263ek_extserial.def \
at91sam9263ek_serial_extusart.reg \

FILE_VIEW_INCLUDES_FOLDER= \
serial.h \

WINCETARGETFILES= \
$(WINCETARGETFILES) \
CopyFilesToSDK \

SDK_H_FILES=
SDK_LIB_FILES=
3、建立一注册表文件,名为at91sam9263ek_serial_extusart.reg
4、修改注册表文件内容。
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_4]
"SysIntr"=dword:2b
; "Irq"=dword:3
"MemBase"=dword:10000070
"MemLen"=dword:8
"Index"=dword:3
"DeviceArrayIndex"=dword:4
"Prefix"="COM"
"Dll"="ext_uart.dll"
"Order"=dword:0
; "Priority256"=dword:fa
; "IsrDll"="isr16550.dll"
; "IsrHandler"="ISRHandler"
"FriendlyName"="Serial Cable on COM4:"

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_5]
"SysIntr"=dword:2c
; "Irq"=dword:3
"MemBase"=dword:10000068
"MemLen"=dword:8
"Index"=dword:4
"DeviceArrayIndex"=dword:5
"Prefix"="COM"
"Dll"="ext_uart.dll"
"Order"=dword:0
; "Priority256"=dword:fa
; "IsrDll"="isr16550.dll"
; "IsrHandler"="ISRHandler"
"FriendlyName"="Serial Cable on COM5:"

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_6]
"SysIntr"=dword:2d
; "Irq"=dword:3
"MemBase"=dword:10000058
"MemLen"=dword:8
"Index"=dword:5
"DeviceArrayIndex"=dword:6
"Prefix"="COM"
"Dll"="ext_uart.dll"
"Order"=dword:0
; "Priority256"=dword:fa
; "IsrDll"="isr16550.dll"
; "IsrHandler"="ISRHandler"
"FriendlyName"="Serial Cable on COM6:"

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_7]
"SysIntr"=dword:2e
; "Irq"=dword:3
"MemBase"=dword:10000038
"MemLen"=dword:8
"Index"=dword:6
"DeviceArrayIndex"=dword:7
"Prefix"="COM"
"Dll"="ext_uart.dll"
"Order"=dword:0
; "Priority256"=dword:fa
; "IsrDll"="isr16550.dll"
; "IsrHandler"="ISRHandler"
"FriendlyName"="Serial Cable on COM7:"
5、将Ext_uart文件夹下mdd.def文件名改为at91sam9263ek_extserial.def
6、在别的驱动文件夹下拷贝文件
makefile.inc文件到Ext_uart文件夹下
7、修改BSP包的CEC文件,添加一扩展串口项
AT91SAM9263 EXTSERIAL
BSP_ AT91SAM9263_EXTSERIAL
BSP_NOEXTSERIAL
8、在PB中加入扩展串口的BSP包,编译,调试。

2008年7月27日星期日

硬件知识 关于LI离子电池保护电路的问题

经常看到这样一种观点:"长时间充电对锂离子电池不会有损害,这是因为有保护电路的存在."   有两个问题要澄清:   
1.长时间对锂离子电池充电,如果是用的原装正品的充电器或座充,确实是不会有损害的.这个不是因为保护线路的功劳,而是充电线路的严格精确的设计来保证的.   
2.有保护线路的存在,并不能完全的防止锂离子电池的过充的发生,保护线路只有在电池过充的时候才会起防止进一步过充的作用.   
这是几个保护芯片的数据 RICOH推出的R5400N系列适合4.2V锂离子电池的保护芯片,其过充保护电压是4.25V-4.35V+/-0.05V,适合4.2V锂离子电池的保护芯片,其过充保护电压是4.275V+/-0.025V   
而锂离子电池充饱的时候,其电池电压应该落在4.20V+/-0.04V之间,并没有触发保护线路动作.之所以厂家说明长时间充电不会过充是因为手机的充电管理确保在电池电压已经到达4.20V以后不会继续充电.而是保持监视状态.   
等到了过充保护的电压,比如4.275V,这个锂离子电池已经是过充了,此时保护线路才被切断.防止进一步过充的危险.   
讲完了这个认识误区,下面带大家认识一下手机锂离子电池的内部机构.主要谈一下锂离子的保护线路的功能及其工作原理.
一般用户接触到手机锂离子电池,在外面看到的除了电池外壳,还有就是几个五金触片了,如图中"电池正极,电池负极"就是的电池正负极输出.
┃ ┏━Fuse━━━━━━━┳━━━━━━━━━┫电池正极      
┃ ┃ R1      
┃ ┃ ┃
┃ ┃ ┃
┃ ┇ ┏┻━━┓      
┃ ┏┻┓       ┃保护IC┃    
┃┏┻━┻┓     ┏┫   ┃    
┃┃   ┃     ┃┗━━┳┛   ┏━━┫标识电阻    
┃┃锂离子┃     ┃   ┃    ┃    
┃┃电芯 ┃     ┃   ┃    R2    
┃┃   ┃     ┃   ┃    ┃    
┃┗━┳━┛     ┃   ┻ Mosfet ┃      
┃ ┃    ┃  ┏╈┓   ┃
┃ ┗━━━━━━━┻━━┻┛┗━━━┻━━┫电池负极
而实际真正供电的源泉是电池塑料壳里面的锂离子电池芯,但是由于锂离子电芯的"娇嫩"的特性,比如过充和过放,大电流放电,短路等非常规动作都会对锂离子电芯造成极大的伤害.所以保护线路的功能就是在上述非常规动作发生时及时的切断回路.保护锂离子电芯.而这些保护动作就是图中的保护IC来判断,由它来控制一对Mosfet场效应管来导通和切断主供电回路,对锂离子电芯进行保护.     市面上常用的这种保护IC的生产厂商有SEIKO精工,RICOH理光,Motorala摩托罗拉半导体等.   以理光R5400N系列芯片来具体介绍各项保护功能.   
众所周知,以恒压充电限制电压来划分,锂离子电池有4.1V恒压充电和4.2V恒压充电两种类型.现在4.1V的版本已经很少,绝大多数是4.2V的恒压充电类型的.下面的数据就只针对4.2V恒压充电的锂离子电池来讨论.     
保护IC+Mosfet可以实现的功能如下(四大保护):   
1.过充保护,当电池芯的电压超过设定值时,由保护IC切断Mosfet管.等电芯电压回归到允许的电压是,重新恢复Mosfet管的导通.   
过充检测电压:4.275V+/-0.025V,电芯电压一超过这个值,就触发过充保护   
过充释放电压:4.175V+/-0.030V,处于过充保护的电芯电压只有降到这个值时才会停止保护.   过充保护延时:1秒.当电压持续超过过充检测电压1秒以上才会触发过充保护,这个是为了防止误判和误操作而设置的.   
2.过放保护,当电池芯的电压降低得超过设定值时,由保护IC切断Mosfet管.等电芯电压回归到允许的电压时,重新恢复Mosfet管的导通.   
过放检测电压:2.3V+/-0.08V   
过放释放电压:2.4V
过放保护延时:125毫秒   
参数的含义与过充保护的类似,不赘述.   
3.过流保护,当工作电流超出设定值时,由保护IC切断Mosfet管.等工作电流回归到允许的电压是,重新恢复Mosfet管的导通.   
过流电流压降:0.1V,这里保护IC判断的是电流流过Mosfet而产生的压降,用这个电压除以Mosfet的导通阻抗就可以近似得到过流保护的电流.一般在3~5A左右.   
4.短路.其实这个功能是过流保护的扩展,当保护IC检测电池输出正负极之间电压小于规定值时,认为此时电池处于短路状态,立即切断回路.等短路的故障排除再恢复回路.短路时电池的输出正负极的电压为零,而实际电芯的电压还是正常的.   
短路检测延时:10微秒,这个延时更是短暂,几乎是短路的瞬间就切断了回路,可以避免短路对电池带来的巨大损伤.   
还有一个参数,称为保护IC的自耗,如上图,可以看到,保护IC是通过电阻R1利用了电芯的电压来进行工作的.不可避免的要消耗一部分电池的容量.一般保护IC的功耗是做的非常小的.在3微安左右,最大不超过6微安.   
在保护回路里面还有一个器件,如上图标示的Fuse,就是保险丝.它是串联在电池的回路中.它的作用是在保护线路失效的情况下,作为最后的防线,对于过流或高温的锂离子电池进行切断回路的动作.该Fuse根据工作原理分为一次性保险丝(就象家里电表下用的那种)和可恢复保险丝(又称为PTC). 有了如此完备的保护线路,一般用户想用坏锂离子电池都有点困难.但是这并不是意味着用户可以随意的滥用锂离子电池.同样有许多的地方是需要注意的.   
下图是根据锂离子电池电压根据实际使用划分的几个区域.      
高压危险区   ---------------保护线路过充保护电压(4.275~4.35V)   
高压警戒区 ---------------锂离子电池充电限制电压4.20V   
正常使用区   ---------------锂离子电池放电终止电压(2.75~3.00V)   
低压警戒区   ---------------保护线路过放保护电压(2.3~2.5V)   
低压危险区      
1.在正常使用区内.锂离子电池可以正常发挥其特性,也没有危险.   
2.高压警戒区.虽然这个区域处于保护线路的保护范围之内,并不意味着此时锂离子电池也是安全的.长期处于这种程度的过充,会很快的降低电池的循环寿命. 据我测试,将新锂离子电池充电到4.3V使用可以比充电到4.2V的锂离子电池提高15%左右的容量,但是在50次循环以后,其容量衰减到原来的 80%,寿命整整缩短了10倍.记得网友battery老兄喜欢把锂离子电池过充了用,这样可以暂时提高前几次循环的容量,容量不够了就换一节新的.我们广大网友恐怕没有这个资本,还是老老实实的使用吧.这种低度过充的锂离子电池往往在几十次循环以后就会产生发鼓等变形.   
3.低压警戒区. 处于该区域的锂离子电池不适合快速充电,要先用小电流将电池电压提升到3.0V以上才可以快速充电.否则容易导致锂离子极性材料发生不良反应,影响电池性能.而这个电压的锂离子电池也非常容易因为电池本身的自耗和锂离子保护线路的自耗很快的掉近低压危险区.那就危险了.而且这个自耗是保护线路无法保护的.   
4.低压危险区,长期处于低压危险区的锂离子电池,性能将近一步恶化. 在低电压(小于2V)或更低的电压情况下,正极材料的钴锂酸(又称尖晶石)晶格发生变化,其晶体机构会以枝晶形式生产.这种枝晶发展长大的话会戳穿正负极的隔膜,导致电池微短路.进一步恶化电池的性能.甚至导致电池发生膨胀,彻底报废.
5.高压危险区.此时保护线路已经失效,或者根本没有保护线路.在这个区域的锂离子电池(特别是4.8V以上),锂离子内部会发生剧烈的反应,产生强大的热量,导致电池内压正极,使电芯变形,不同于低度过充,这种变化是一次性的,即一次高度过充就可以造成电池发鼓.甚至爆炸.
以下是几点锂离子电池的与保护线路相关的注意事项   
1.不要试图直接短路锂离子电池来强行放电.这样做只有两种结果,一是保护线路起作用,那么什么事也不会发生.二是保护线路失效,那样就会造成过流或直接电芯的短路,就会触发fuse动作,如果里面也没有fuse的保护(很多杂牌锂离子电池就是没有fuse或PTC),那么这种短路的瞬间电流将达到十几甚至几十安培,足以烧毁线路板,使导线发红.要是碰上皮肤那就更惨了.   
2.不要使用不合格(没有认证)的充电器或座充,锂离子电池的充电过充需要严格的电压控制,这点做的不好的充电器会对锂离子电池造成低度过充,虽然最后有保护线路的保护,但是已经过充了.   3.不要在电池两端加高压,保护芯片也有极限的承受电压,一般在12V左右,在往上往往会击穿保护芯片.   
4.不要逆接电池正负极进行充电,同样会损伤保护IC   
5.注意锂离子电池的使用环境,潮湿,高温,静电会导致保护IC或Mosfet失效的.手机落入水中,在记得吹干手机主板的同时,也要对锂离子电池进行晾干处理,但不要用电吹风吹干.高温(60度以上)对锂离子电池是有害的.
很有趣的是第一点.有兴趣的网友可以根据锂离子电池保护线路的短路保护功能来测试一下你的保护线路是否有效.最后找一个指针式的直流电流表(5A量程左右),对电池的正负极直接短路,你可以看到电流表指针会动一下并迅速归零.这就说明在几个微妙之内保护线路已经动作了.这是检测你的锂离子电池有没有保护线路的一个简单有效的办法.采用数字式的电流表也行,都要把量程设成最大的安培档(2A以上的).        
以上谈论的是单节锂离子电池的保护线路,不包括串联两节以上的保护IC,道理大同小异.      在第一个图中,画了一个标识电阻R2,如果这个电阻是个常规的定值电阻,那么就是手机用来区别电池类型用的.三星的手机在隐藏菜单中可以看到这个电阻值.他们的手机用不同的电阻来区分不同容量的电池(厚薄电)如果这个电池是个热敏电阻(NTC),那么它就可以告诉手机或充电器电池的温度,因此手机或充电器就有了对电池温度的检测能力.当电池温度超出范围(比如0度~40度以外),手机或座充就不对锂离子电池进行充电动作.这也是对锂离子电池的保护.   
有些电池会有两个以上的标识电阻(一个常规电阻,一个热敏电阻)或专用的识别芯片来执行这个功能.原理都是一样的.目的就是确保更好的的使用锂离子电池.

硬件知识

硬件技术 MIC的结构、原理、性能参数

一、MIC的电路原理
C:是一个可以通过膜片震动而改变电容量的电容,声电转换的主要部件。
FET:(场效应管)MIC的主要器件,起到阻抗变换和放大的作用。
C1,C2:是为了防止射频干扰而设置的,可以分别对两个射频频段的干扰起到抑制作用。
C1一般是10PF,C2一般是33PF,10PF滤波1800Mhz,33PF滤波GSM900Mhz。
RL:负载电阻,它的大小决定灵敏度的高低。
VS:工作电压,MIC提供工作电压。
Co::隔直电容,信号输出端。
二、由声信号到电信号的转换原理
由静电学可知,对于平行板电容器,有如下的关系式:C=ε·S/L① 即电容的容量与介质的介电常数成正比,与两个极板的面积成正比,与两个极板之间的距离成反比。另外,当一个电容器充有Q量的电荷,那麽电容器两个极板要形成一定的电压,有如下关系式;C=Q/V② 对于一个驻极体传声器,内部存在一个由振膜,垫片和极板组成的电容器,因为膜片上充有电荷,并且是一个塑料膜,因此当膜片受到声压强的作用,膜片要产生振动,从而改变了膜片与极板之间的距离,从而改变了电容器两个极板之间的距离,产生了一个Δd的变化,因此由公式①可知,必然要产生一个ΔC的变化,由公式②又知,由于ΔC的变化,充电电荷又是固定不变的,因此必然产生一个ΔV的变化。由于这个信号非常微弱,内阻非常高,不能直接使用,因此还要进行阻抗变换和放大。FET场效应管是一个电压控制元件,漏极的输出电流受源极与栅极电压的控制。由于电容器的两个极是接到FET的S极和G极的,因此相当于FET的S极与G极之间加了一个Δv的变化量,FET的漏极电流I就产生一个ΔID的变化量,因此这个电流的变化量就在电阻RL上产生一个ΔVD的变化量,这个电压的变化量就可以通过电容C0输出,这个电压的变化量是由声压引起的,因此整个传声器就完成了一个声电的转换过程。

三、参数
在讲参数之前讲讲驻极体
驻极体是一种能长久保持电极化状态的电介质,这种电介质是一种高分子聚合物,它的工作原理是电容式的:由一片单面涂有金属的振动膜与一个带有若干小孔贴有驻极体薄膜的金属电极(称为背极)构成。驻极体面与振动膜相对,中间有一极小的空气隙,这就形成一个以空气隙和驻极体作绝缘介质,以背极和振动膜上的金属层作为两个电极的介质电容器,电容器的两极之间并接一只电阻,这只电阻是麦克风的阻抗变换器或前置放大器的输入电阻。由于驻极体上分布有自由电荷,于是在电容器的两极之间就有了电荷量,当声波使振动膜振动而产生位移时,改变了电容器的电容量,电容量的改变使电容器的输出端产生了相应的交变电场,交变电场作用于R就形成了与声波信号对应的电信号,于是就完成子声——电转换的功能。
驻极体麦克风是按电容式原理工作的,因此它具有电容式电声器件的很多优点,如频带宽、音质好、失真小、瞬态响应好,对机械振动不敏感等特点。
下面以麦克风的主要电声性能为例讲述有关设计理论。

1、输出阻抗 影响驻极体麦克风阻抗的主要因素是阻抗变换器或放大器的输出阻抗。对手机用驻极体麦克风而言,阻抗变换器或放大器的输出阻抗主要决定于场效应管(FET)与输出端并接的两只抗RF干扰的滤波电容,由于FET及电容的性能有差异,因此驻极体麦克风的输出阻抗会在一定范畴内变化,选用一致性、稳定性好的FET及电容,严格控制SMT等生产过程,可使阻抗性能的一致性和稳定性达到理想状态。

2、灵敏度 影响驻极体麦克风灵敏度的因素较多,归纳起来主要有以下几项:
A、驻极体表面电荷密度的大小
B、振膜的张力
C、振膜与背极间的距离
D、阻抗变换器或放大器的性能。
驻极体麦克风的灵敏度与驻极体表面电荷密度成正比。表面电荷密度越大,则驻极体麦克风灵敏度就越高。但驻极体表面电荷密度过大将会导致振膜附到背极上,使麦克风处于不稳定状态。解决的办法是增大振膜与背极的距离或增加膜片的张力,由此会导致灵敏度降低和频响曲线改变。另外表面电荷密度大,其稳定性就差,因此对客户要求的灵敏度来讲应选取合适的电荷密度,确保其稳定性。 驻极体麦克风的灵敏度与振膜的张力成反比关系。张力越大灵敏度就越低,张力越小灵敏度就越高,但张力的大小会受材料及生产工艺的影响,振膜张力过大可导致振膜产生不可逆的蠕变,从而影响稳定性。振膜张力过小可使频响变差,同样出现性能不稳定。因此对客户要求的灵敏度来讲应选取合理的张力设计,确保其性能稳定。 麦克风的灵敏度同振膜与背极间距成反比关系。间距越大,灵敏度就越低;间距越小,灵敏度就越高。合理的间距设计需考虑客户对灵敏度的要求及稳定性的好坏等多方面的因素。 麦克风的灵敏度同阻抗变换器(放大器的影响量)成正比关系。FET放大倍数越大,则灵敏度高。过大的放大量会导致噪音的增大,影响使用效果。合适的放大量或合适的阻抗对灵敏度设计的影响是很重要的。 在影响灵敏度的诸多因素之间,我们会根据客户的需要综合考虑,不是片面追求灵敏度的高低为目标,而应以追求稳定性为目标。

3、频率响应 影响驻极体麦克风的频率响应的因素有振膜的张力、背极板上孔的数量、孔径的大小、孔位以及与孔相连的后腔体积大小等。对一个已经定型的驻极体麦克风而言,其背极板上孔径、孔位及孔的数量均已确定与孔相连的后腔体积也已基本确定,而容易变化的则是振膜的张力,振膜的张力大,它的共振频率就高,驻极体麦克风的频率响应就平坦。但张力过大,长时间工作,同样使振膜产生不可逆的蠕变,从而影响麦克风的稳定性。除振膜张力影响频率响应外,FET的频率特性及由于生产过程封变影响造成180度方向产生过大的声压作用等也会影响麦克风的频率响应。

4、信噪比(S/N) 影响信噪比(S/N)的因素很多:设计时应考虑PCB的高频分布电容,分布电感; 阻抗的匹配,RF的干扰,FET的本底噪音,电容极头的屏蔽性,接地电阻等诸多因素。 解决以上问题,从抗高频干扰角度合理设计PCB布线,并经严格的IQC检测;选用优质低噪的FET,并加抗RF干扰电容;严格极头制作工艺和装配工艺,使噪音降到最小,从而使S/N达到理想的最大值。

5.指向性 又称为方向性,是指传声器对不同角度入射的声波的响应。当声波以不同角度入射到振漠时,振膜所受到的作用力不同,相应的输出也不同。这种因入射声波的入射角不同而使传声器灵敏度产生变化的特性,称为传声器的指向性。这里的声波入射角是声波与振膜法线的角。
在工作中,避免数学计算,通常采用极坐标图形表示。称为传声器指向性图形。有时也采用不同入射角的频响曲线表示法。
话筒的指向:分为心形、超心形、8字形、枪式、全向指向等。见下图

至于这些指向究竟是怎么回事,你可找个话筒试试。如图中,箭头所指方向为话筒所指正前方,虚线为可拾音的大致范围,在范围之外,拾音将不灵敏。有条件,建议还是找个多指向的话筒试用一下,就知道怎么回事了。
6.降电压特性、最大工作电压及消耗电流 降电压特性、最大工作电压及消耗电流主要取决于FET的性能。设计时针对不同客户,通过FET设计验证结果择优选用,使降电压特性的变化最小,使最大工作电压及消耗电流的余量最大。消耗电流除受FET出厂性能影响外,实际的生产环境洁净度、湿度等因素也必须考虑。

四、应用实例

MIC在手机上的使用条件,其中包括工作电压,负载电阻。另外在以下情况下还要对MIC的工作电流进行限定,例如有的手机给MIC的供电电压为1.8V,而负载电阻为2.2K,因为Vd=Vsd+Id*R, Id = (Vs- Vsd)/ RL为了保证MIC中的FET工作在线性工作区,不进入饱和区,应使Vsd≥0.7V,因此Id≤(1.8V- 0.7V)/ 2.2K=0.5 mA,因此在这种情况下,选用的FET的电流不能大于500μA。从下面这个MIC的参数就可以看的出来。
灵敏度 -43+/-2dB RL=2.2KΩ Vs=2.0V(DC)(1KHz 0dB=1V/Pa)
输出电阻 最大2.2KΩ 1KHz(RL=2.2KΩ)
频率 50-12000Hz
电流损耗 最大0.5mA RL=2.2KΩ Vs=2.0V(DC)
操作电压范围 1.0V-10V(DC)
最大输出声压 115dB S.P.L
信噪比 58dB 1KHz,0dB=1V/Pa
灵敏度变化 2.0V-1.5V灵敏度减小3dB

2008年7月24日星期四

经济学常识 “次贷危机”是货币经济下经济危机的表现形式!

现代商品经济与传统商品经济有什么不同?其不同点仅在于“国家货币”的出现。就其分水岭,就是基于凯恩斯思想的“新经济模式”。

据考证,我国的“国家货币”早在1000年前的宋朝就有了,还有人考证,宋朝就是亡于通货膨胀,与蒋氏民国之亡有点类似

马克思主义政治经济学中经济危机的原理并未过时,但它推导的“经济危机”的结论,只是道出了经济运行秩序在数理的不可能再循环关系,而他又跳跃地道出了人类社会运动的关系上,会出现新的社会形式或新的“朝代”的必然,这是需要分辩开的。

货币经济的出现,使得经济数理关系的不能顺利循环,并不一定导致社会形态变迁的必然(现代社会的政治关系,则更是可以换一届政府而不必亡国),但它最简单直接的结果,是造成会计帐面的的“坏帐”或所需的“撇帐”。凯恩期的国家注资干预,只是其中的一种具体的进一步的表现形式罢了。

这次次贷危机,本质就是经济危机的一种,是现代货币经济下的经济危机的一种,要缓和它的后果与冲击,最快的只能靠央行注资,而另一方面,它后续还需要对民间消费(货币)关系的重新注入。

现代经济与传统经济还有一样不同的是,某一国的货币会被它国接受。如中国就接受了15000亿美元。所以,如果中国愿将其美元货币以某一种形式(如美国国债)回流到美国的话,也相当于一种政府的注资,为美国人解了围。如果说这种做法,相当于中国人民为美国人的住房消费永远埋单,则是另一回事了。

就次贷危机的现实,之后的美国是“美联储注资度日”还是“美国借国债度日”,本质是没有太大分别的,美国经济体从原则上讲是不会出很大的问题,只是“帐”算到谁的头上。全世界的人民自愿地继续那么喜欢美元,美国人不用说谢谢也是可以的。

经济学常识 没有硝烟的掠夺,日本佬被搞得很惨

1980年,日本的GDP就快到美国的一半了。但有一件事情却在1985年发生了。

1985年美国拉拢其它五国(7国集团)逼迫日本签署了广场协议。以“行政手段”迫使日元升值。其实的一个中心思想就是日本央行不得“过度”干预外汇市场。日本当时手头有充足的美元外汇储备,如果日本央行干预,日元升不了值。可惜呀,日本是被去了势的太监。美国驻军、政治渗透、连宪法都是美国人帮它度身定做的,想不签广场协议都不可能。日本最后的结局大家也知道了。

1985年9月的广场协议至1988年初.美国要求日元升值。根据协议推高日元,日元兑美元的汇率从协议前的1美元兑240日元上升到1986年5月时的1美元兑160日元。由于美国里根政府坚持认为日元升值仍不到位,通过口头干预等形式继续推高日元。这样,到1988年年初,日元兑美元的汇率进一步上升到1美元兑120日元,正好比广场协议之前的汇率上升了一倍。

美国人满足了吗?没有。接着看下去,从1993年2月至1995年4月,当时克林顿政府的财政部长贝茨明确表示,为了纠正日美贸易的不均衡,需要有20左右的日元升值,当时的日元汇率大致在1美元兑120日元左右,所以,根据美国政府的诱导目标,日元行情很快上升到1美元兑100日元。以后,由于克林顿政府对以汽车摩擦为核心的日美经济关系采取比较严厉的态度。到了1995年4月,日元的汇率急升至1美元兑79日元,创下历史最高记录。

日元升值的后果是什么?洛克菲勒广场重新回到了美国人手中,通用汽车在这个广场的一卖一买中净赚4亿美元!日资在艰难度日中大规模亏本退出美国。美国人民胜利了!成功的击退了日本的经济进攻!我们可以从事例中看看1995年之后,日本和美国的GDP之比重新拉开了距离,而且越来越大!

可能有些网友还是没有明白,日元升值怎么啦?跟我们的谈论有什么关系?日元升值,就是美国对日本的一次经济阻击战!成功的把日本20多年的发展财富大转移到了美国去了。

时下美元对人民币汇率一降再降,人民币连续升值,这是美国佬的又一次掠夺开始了。

开心一刻 人和猪的关系

人=吃饭+睡觉+上班+玩  
猪=吃饭+睡觉  
人=猪+上班+玩  
人-玩=猪+上班  
结论:不懂玩的人=会上班的猪

男人=吃饭+睡觉+挣钱  
猪=吃饭+睡觉  
男人=猪+挣钱  
猪=男人-挣钱  
结论:男人不挣钱等于猪

女人=吃饭+睡觉+花钱  
猪=吃饭+睡觉  
女人=猪+花钱  
女人-花钱=猪  
结论:女人不花钱的都是猪

综合以上: 男人为了让女人不变成猪而挣钱  
女人为了让男人不变成猪而花钱   
男人+女人=猪+挣钱+猪+花钱=两头猪

wince学习 wince下的一些小技巧

要重新建立文件系统时,必需要先擦除原来的文件系统。
不知道为什么???

注意大小写;
Bsp包的名字一定要大写。例如:BSP_TIMER_DRIVER
前缀名要大写
由"Prefix"="TIM"定义
在.cpp文件中要使用的,它最长允许3个字母。

代码驱动的加载方法;
一是由设备管理器直接加载管理
二是由用户程序加载,用户程序直接调用.dll加载,然后直接使用其内部封装的函数。


可以用Build OS下的open release directory窗口的set命令来查看编译的所有的关联信息。
可以看加入的组件有什么。


EP9315公板原来的Wince5.0BSP包的RTC会隔一段时间就区读时间。

Wince的中文包一般在10M左右
如果flash的大小不够的话就要考虑是否要用中文了。

在Driver目录下的目录中总能找到一个文件中有如下函数:
extern DWORD XXXX_Init(DWORD dwContext)
extern BOOL XXXX_Deinit(DWORD hDeviceContext)
extern DWORD XXXX_Open(DWORD hDeviceContext, DWORD AccessCode,
DWORD ShareMode)
extern BOOL XXXX_Close(DWORD hOpenContext)
extern BOOL XXXX_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
extern DWORD XXXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
extern DWORD XXXX_Write(DWORD hOpenContext, LPCVOID pSourceBytes,
DWORD NumberOfBytes)
extern DWORD XXXX_Seek(DWORD hOpenContext, LONG Amount, DWORD Type)
extern void XXXX_PowerUp(DWORD hDeviceContext)
extern void XXXX_PowerDown(DWORD hDeviceContext)
这些函数就构成了驱动的一个结构。


Wince下删除工程的方法
可能有时候在建立工程时忘记或者时多选了某些选项,但是这个错误的工程又占用了你的工程名,因此你就可能想删除这个错误的工程。
操作步骤:
1、 保证工程没有被打开
2、 进入manage item catalog,删除此工程使用的BSP包
3、 进入PBWorkspaces下,删除你想删除的工程文件夹。
希望你不会报错。

wince学习 wince下将EP9315用两个调试串口改为一个的方法

EP9315下载口和调试口不是用的同一个串口,这样用起来不方便。
下面是修改成同一个串口的方法:
1、在BSP 文件安装目录 \WINCE500\PLATFORM\Ep93xx\Src\Kernel\Hal\Common\ 下, 寻找到文件
“debug.c”,打开文件,对串口配置进行修改;
#ifndef DEBUG_UART_PORT //( 约57行 )
#define DEBUG_UART_PORT 1 // 3,进行修改,改用COM1为调试串口
#endif // DEBUG_UART_PORT
2、在BSP文件安装目录 \WINCE500\PLATFORM\Ep93xx\Src\Inc\下,寻找到文件“options.h”,打开文件,对串
口配置进行修改;
#ifdef EDB9307_12_15 //( 约43行 )
#define EBOOT_PLATFORM_STRING "EDB9307/1X"
#define EBOOT_CS8950_MAC_ADDRESS {0x2400, 0x1020, 0x5678}
#define DEBUG_UART_SPEED 38400
#define DEBUG_UART_PORT 1 // 3,进行修改,改用COM1为调试串口
3、在BSP 文件安装目录 \WINCE500\PLATFORM\Ep93xxSrc\Kernel\Hal\Common\ 下, 寻找到文件
“oempreinit.c”,用编辑工具打开文件,对串口配置部分进行修改;
……//(约70行)
//*CSC_DEVCFG = DEVCFG_U1EN DEVCFG_U2EN DEVCFG_U3EN DEVCFG_TIN DEVCFG_SHENA //modify for com1
*CSC_DEVCFG = DEVCFG_U1EN DEVCFG_U2EN DEVCFG_U3EN DEVCFG_TIN DEVCFG_CPENA
DEVCFG_SHENA
#ifndef EDB9301_02
// Trun off IrDA on UART2 because EDB9301/02 have not implement it.
; // DEVCFG_IONU2
4、在BSP文件安装目录 \WINCE500\PLATFORM\Ep93xx\Files下,寻找到文件“platform-1x07.reg”,用编辑工具打开文件,对串口配置部分进行修改;
IF BSP_EP93XX_SERIAL
;[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_1]
; "DeviceArrayIndex"=dword:1
; "Prefix"="COM"
; "Dll"="pl010serial.Dll"
; "Order"=dword:0
;[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_1\Unimodem]
; "Tsp"="Unimodem.dll"
; "DeviceType"=dword:0
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_2]
"DeviceArrayIndex"=dword:2
"Prefix"="COM"
"Dll"="pl010serial.Dll"
"Order"=dword:0
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial_3]
"DeviceArrayIndex"=dword:3
"Prefix"="COM"
"Dll"="pl010serial.Dll"
"Order"=dword:0
ENDIF

当然按照这种方法,也可以不要调试口。将调试串口改成普通串口用。

wince学习 将wince内核编译成-NK保存在norflash中,然后从norflash读到SDRAM运行模式

将wince内核编译成-NK保存在norflash中,然后从norflash读到SDRAM运行模式

1、加组件BSP_EP93XX_COPY_FLASH_TO_RAM

2、修改E:\WINCE500\PLATFORM\Ep93xx\Src\Kernel\Hal\Edb9307_1x下的startup.s文件

将下面的几句在原文中注释掉。
; mov sp, #0x40000
; bl SysconSetup

; create a temporary stack below kernel memory from config.bib

ExecuteFromRam
; mov sp, #0x40000
; bl SysconSetup

; clear out magic words for memory and heap
; (r0) = physical address of OEMAddressTable
; Calculate the physical address of the table.

然后把这两句拷贝到下面的位置
;
; Configure the flash chips
;
IF EP93XX_FLASH_TYPE = "FLASH_TYPE_AMD" :LOR:\
EP93XX_FLASH_TYPE = "FLASH_TYPE_C3" :LOR: \
EP93XX_FLASH_TYPE = "FLASH_TYPE_P3"

ldr r0, =0x2000FFEF

ELSE
ldr r0, =((4:SHL:SMCBCR_WST2_SHIFT) :or: \
(15:SHL:SMCBCR_WST1_SHIFT) :or: \
(1 :and:SMCBCR_IDCY_MASK) :or: \
SMCBCR_MW_32BIT :or: \
SMCBCR_WP :or: \
SMCBCR_PME :or: \
SMCBCR_RBLE)

ENDIF

ldr r1, =0x80080018
str r0, [r1]
nop
;This sets up the System Control Registers。To set clock tree and the SMC timings.

mov sp, #0x40000
bl SysconSetup

; If we want an image that copies from flash to ram use the following.

IF COPY_FLASH_TO_RAM ;开始拷贝NK到SDRAM






上面这段的目的就是在拷贝前先将SMC和NORFlash初始化。

也可以在此驱动LCD,然后将LOGO图片数据先弄出来,系统就会显示LOGO。
这就是一些公司引以自豪的LOGO方案。

wince学习 wince下MMU虚拟地址对实际地址转换表

wince下MMU虚拟地址对实际地址转换表

在\WINCE500\PLATFORM\yourplatform\Src\Inc文件夹下cfg.inc文件定义
;------------------------------------------------------------------------------
; FirstBoot Param !! these values are also defined in bsp_cfg.h. Modify both files if needed !!
;------------------------------------------------------------------------------
FIRSTBOOT_MAX_SIZE EQU 0x00007800 ;30 ko
FREE_AREA_SIZE EQU 0x00000800 ; 2 ko
AT91C_RAM_MAX_SIZE EQU 0x00008000 ;32 ko

;------------------------------------------------------------------------------
; EBoot Param !! these values are also defined in bsp_cfg.h. Modify both files if needed !!
;------------------------------------------------------------------------------
EBOOT_MAX_SIZE EQU 0x00014000 ;80ko
OEM_RESERVED_MEMORY_SIZE EQU 0x2000 ;8ko
EBOOT_FLASH_ADDR EQU FIRSTBOOT_MAX_SIZE + FREE_AREA_SIZE + OEM_RESERVED_MEMORY_SIZE

; Export Definition

EXPORT g_oalAddressTable[DATA]

; Make sure that this value match with those in eboot.bib and config.bib

AT91SAM9261EK_VA_BASE_REG EQU 0x9FF00000
AT91SAM9261EK_VA_BASE_DM9000 EQU 0x9FE00000
AT91SAM9261EK_VA_BASE_NAND EQU 0x9EA00000
AT91SAM9261EK_VA_BASE_SRAM EQU 0x9E700000
AT91SAM9261EK_VA_BASE_NOR EQU 0x9DF00000
AT91SAM9261EK_VA_BASE_SDRAM EQU 0x80000000

AT91SAM9261EK_BASE_SRAM EQU 0x00300000
AT91SAM9261EK_BASE_SDRAM EQU 0x20000000
AT91SAM9261EK_BASE_DM9000 EQU 0x30000000
AT91SAM9261EK_BASE_NAND EQU 0x40000000
AT91SAM9261EK_BASE_NOR EQU 0x10000000
AT91SAM9261EK_BASE_REG EQU 0xFFF00000

;------------------------------------------------------------------------------
; TABLE FORMAT
; cached address, physical address, size
;------------------------------------------------------------------------------
ALIGN
g_oalAddressTable

DCD AT91SAM9261EK_VA_BASE_SDRAM, AT91SAM9261EK_BASE_SDRAM, 64
; AT91SAM9261EK SDRAM (64MB).
DCD AT91SAM9261EK_VA_BASE_NOR, AT91SAM9261EK_BASE_NOR, 8
; NOR Flash memory (8MB).
DCD AT91SAM9261EK_VA_BASE_SRAM, AT91SAM9261EK_BASE_SRAM, 1
; INTERNAL SRAM (160KB).
DCD AT91SAM9261EK_VA_BASE_NAND, AT91SAM9261EK_BASE_NAND, 5
; NAND Flash memory (1MB).
DCD AT91SAM9261EK_VA_BASE_DM9000, AT91SAM9261EK_BASE_DM9000, 1
; DM9000 registers.
DCD AT91SAM9261EK_VA_BASE_REG, AT91SAM9261EK_BASE_REG, 1
; Internal registers.
DCD 0x00000000, 0x00000000, 0
; end of table

;------------------------------------------------------------------------------
END

wince学习 wince5.0组件及其相关连组件选择

wince5.0组件及其相关连组件选择。

usb设备驱动:
core os
core os services
usb host support
usb human input
usb HID keboard and mouse--USB键盘和鼠标
usb HID keboard only--USB键盘
usb HID mouse only--USB鼠标
usb storage class driver--U盘驱动

如果要运行EVC程序,一般要加MFC组建
application and service devlopment
Microsoft Foundation classes (MFC)

如果是加了CF卡或者是PC卡要加下面组件
device drivers
Storage Device
compact flash/Pc card storage

如果是加了IDE硬盘就要加下面组件
device drivers
Storage Device
ATAPI PCI/IDE storage block Driver
ATAPI PCI/IDE Storage Block Driver
Promise controler ATAPI driver

如果是要加矩阵键盘,要加如下的组件
Third Party
BSPs
EAC0921
device driver
EP93XX Cherry US English keypad

加了存储设备之后一定要记得加文件系统组件
core os
windows ce device
file system and data store
storage manage
FAT file system

要调试的话就要加下面的组件
Platform manager
Platform manager

要将注册表保存到flash中的话就要加Hive-Base registry
core os
windows ce device
file system and data store
registry storge (choose 1)
Hive-Base registry
Ram-Base registry

wince学习 wince下cs4202音频芯片驱动注册表修改

wince下cs4202音频芯片驱动注册表修改
如果要使用cs4202的音频芯片,一定要记得取消UseAC97项前的注释

IF BSP_EP93XX_AUDIO
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\WaveDev]
"Prefix"="WAV"
"Dll"="wavedev.dll"
"Index"=dword:1
"Order"=dword:0
; Specify support I2S codec support
; "I2SCodec"=dword: 10af - CS4271, 1084 - CS4228, default:4228

; Use I2SVolume Control for Wave Volume.
; Note: The I2S volume control interferes with the PS/2 Keyboard.
; This is why it is used.
; "UseI2SVolumeControl"=dword:1 ; 0- disabled, 1 - Enabled , defualt 1
; ************************************************************************
; AC97 Hardware Settings
; EDB9312 board:
; Make sure the JP67, JP68, JP70- JP72 are jumpered 2-3 for
; AC97 audio and 1-2 for I2S audio.
; EDB9315 & EDB9307 board:
; JP2 is jumpered for I2S and open for AC97 audio.
; ************************************************************************
"IClass"=multi_sz:"{E92BC203-8354-4043-A06F-2A170BF6F227}",
"{37168569-61C4-45fd-BD54-9442C7DBA46F}",
"{A32942B7-920C-486b-B0E6-92A702A99B35}"

; Uncomment the following lines to enable AC97 audio and disable I2S audio:
"UseAC97"=dword:1

ENDIF

注册表的修改涉及到很多的东西,尤其是很多的键值。
驱动中可能会调用一些键值来配置程序等、

一般是根据别人的可用的工程的键值来修改。这也是wince的开发方法。

wince学习 wince将注册表保存到norflash中的方法

wince将注册表保存到norflash中的方法

1、必须保证norflash已经驱动了。

2、添加组件
将registry storage(choose 1)下的Hive-Base registry添加到工程

3、修改注册表。
IF BSP_EP93XX_FLASH
; This file is to be included in platform.reg if required.
;
; It use the top 4MB space of flash (EDB931x):
; uncached base address = A9e00000; memory size= 200000

IF BSP_SAVEDREGISTRY_NORFLASH !

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NORFlash]
"Dll"="ep93xxnorflash.dll"
"Order"=dword:2
"Prefix"="DSK"
"Ioctl"=dword:4
"Profile"="MSFlash"
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
"MemBase"=multi_sz:"A8000000","A9e00000"
"MemLen" =multi_sz:"2000000","200000"

; Override names in default profile[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
"Name"="Ep93xx NOR Flash"
"Folder"="NORFlash"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1

[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\MSFlash] "DriverPath"="Drivers\\BuiltIn\\NORFlash"
; LoadFlags 0x01 == load synchronously
"LoadFlags"=dword:1
"Order"=dword:0

ENDIF ;END NO SAVE REGISTRY IN NORFLASH

IF BSP_SAVEDREGISTRY_NORFLASH
;;;*******************************************************************
;;;;;; HIVE REGISTRY BOOT SECTION
;;;;;;*******************************************************************

;真正的保存设置是下面这一项而已。
[HKEY_LOCAL_MACHINE\init\BootVars]
"SystemHive"="system.hv"
"Start DevMgr"=dword:1
"DefaultUser"="default"
"Flags"=dword:1
"RegistryFlags"=dword:0

;其实下面的都是norflash的属性,
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NORFlash]
"Dll"="ep93xxnorflash.dll"
"Order"=dword:0
"Prefix"="DSK"
"Ioctl"=dword:4
"Profile"="NORFlash"
"Flags"=dword:1000
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
"MemBase"=multi_sz:"A8000000","A9e00000" ;文件系统信息
"MemLen" =multi_sz:"2000000","200000"

;;; Override names in default profile在根目录显示的属性[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NORFlash]
"Name"="Ep93xx NOR Flash"
"Folder"="NORFlash"
"DefaultFileSystem"="FATFS"
"PartitionDriver"="mspart.dll"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1

;文件系统属性
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\NORFlash\FATFS] "Dll"="fatfsd.dll"
"Flags"=dword:00000000
"Util"="fatutil.dll"
"Paging"=dword:1
"CacheSize"=dword:0
"EnableCache"=dword:0
"MountFlags"=dword:2

;[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\NORFlash]
; "DriverPath"="Drivers\\BuiltIn\\NORFlash"
; LoadFlags 0x01 == load synchronously
; "LoadFlags"=dword:1
; "BootPhase"=dword:0
; "Order"=dword:0

;
[HKEY_LOCAL_MACHINE\System\StorageManager\FATFS]
"EnableCache"=dword:0
"CacheSize"=dword:0

ENDIF ; END HIVE BOOT SECTION


ENDIF ;END IF BSP_EP93XX_FLASH

编译内核,下载。在第一次启动时系统会建立文件系统。

wince学习 wince下修改norflash的文件系统大小

修改norflash的文件系统大小方法如下:

1、修改注册表文件下面的字段
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NORFlash]
"Dll"="ep93xxnorflash.dll"
"Order"=dword:2
"Prefix"="DSK"
"Ioctl"=dword:4
"Profile"="MSFlash"
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
#if $(BSP_EP93XX_FLASH_TYPE) == FLASH_TYPE_P3
"MemBase"=multi_sz:"A8000000","AA000000"
"MemLen" =multi_sz:"4000000","2000000"
#elif $(BSP_EP93XX_FLASH_TYPE) == FLASH_TYPE_C3
"MemBase"=multi_sz:"A8000000","A8400000"
"MemLen" =multi_sz:"800000","200000"
#elif $(BSP_EP93XX_FLASH_TYPE) == FLASH_TYPE_AMD
"MemBase"=multi_sz:"A8000000","A8400000"
"MemLen" =multi_sz:"1000000","200000"
#else
"MemBase"=multi_sz:"A8000000","A9800000"
"MemLen" =multi_sz:"2000000","800000"
#endif
修改MemBase和MemLen的值
记得要A8000000+2000000=A9800000+800000
前面两个数表示的是整个norflash的起始地址和大小。
后面两个数表示的是文件系统起始地址和大小。

2、修改.BIB文件,将内核的大小改小。
不过一定要注意实际编译出来的大小不能超过你设定的大小。否则会出错。
IF IMGFLASH !
IF BSP_EP93XX_COPY_FLASH_TO_RAM
;**********************************************************************
; Copy Flash to RAM and boot from RAM.
;**********************************************************************
MEMORY
RESERVED 80000000 00008000 RESERVED
DRV_GLB 80008000 00001000 RESERVED
CS8950 80010000 00030000 RESERVED
EDBG 80040000 00080000 RESERVED
FRAMEBUF 800C0000 00200000 RESERVED
NK 802C0000 01800000 RAMIMAGE
RAM 82000000 02000000 RAM
CONFIG
COMPRESSION=ON
PROFILE=OFF
ROMSTART=802C0000
ROMSIZE=01800000
ROMWIDTH=32
;
; NKStart + ROMOFFSET = Physical Memory Location.
; 0x802C0000 + 0xDFD40000 = 0x60000000
ROMOFFSET=DFD40000
ROMFLAGS=0
KERNELFIXUPS=ON
AUTOSIZE=OFF
ENDIF
ENDIF
在.bib文件中有三种启动模式,看你选择的是那种启动模式,
无论那种模式,你只要将下行中大小字段修改成你想要的大小。

NK 802C0000 01800000 RAMIMAGE
将01800000修改成你的大小。

ROMSIZE=01800000
将ROMSIZE也修改成上面相同的大小。

硬件技术 关于AT91SAM9261总线矩阵map、remap和启动的问题。

关于AT91SAM9261总线矩阵map、remap和启动的问题。

The Bus Matrix manages five Masters and five Slaves.


Each Master has its own bus and its own decoder, thus allowing a different memory mapping
per Master.
Each Slave has its own arbiter, thus allowing a different arbitration per Slave.
According to upper, The Bus Matrix provides one decoder for every AHB Master Interface. The decoder offers each AHB Master several memory mappings. Depending on the product, each memory area may be assigned to several slaves. Booting at the same address while using different AHB slaves (i.e.,external RAM, internal ROM, internal Flash, etc.) becomes possible.

For Master 0 and Master 1 (ARM926™ Instruction and Data), three different Slaves are assigned to the memory space decoded at address 0x0: one for internal boot, one for external boot, one after remap. Refer to Table 8-3 for details.
Boot Strategies
almost all systems boots at address 0x0. To ensure a maximum number of possibilities for boot,the memory layout can be configured with two parameters.
REMAP allows the user to lay out the first internal SRAM bank to 0x0 to ease development. This is done by software once the system has booted for each Master of the Bus Matrix.
When REMAP = 1, BMS is ignored. Refer to the Bus Matrix Section for more details.
When REMAP = 0, BMS allows the user to lay out to 0x0, at his convenience, the ROM or an
external memory.
This is done via hardware at reset.
Note: Memory blocks not affected by these parameters can always be seen at their specified base
addresses. See the complete memory map presented in Figure 8-1 on page 16.
The AT91SAM9261S Bus Matrix manages a boot memory that depends on the level on the
BMS pin at reset.
The internal memory area mapped between address 0x0 and 0x000F FFFF is reserved for this purpose.
If BMS is detected at 1, the boot memory is the embedded ROM.
If BMS is detected at 0, the boot memory is the memory connected on the Chip Select 0 of the
External Bus Interface.


BMS = 1, Boot on Embedded ROM
The system boots using the Boot Program.
• DataFlash Boot
– Downloads and runs an application from SPI DataFlash into internal SRAM
– Downloaded code size from SPI DataFlash depends on embedded SRAM size
– Automatic detection of valid application
– SPI DataFlash connected to SPI NPCS0
• NANDFlash Boot
• Boot Uploader in case no valid program is detected in external SPI DataFlash
– Small monitor functionalities (read/write/run) interface with SAM-BA™ application
– Automatic detection of the communication link
Serial communication on a DBGU (XModem protocol)
USB Device Port (CDC Protocol)
BMS = 0, Boot on External Memory
• Boot on slow clock (32,768 Hz)
• Boot with the default configuration for the Static Memory Controller, byte select mode, 16-bit
data bus, Read/Write controlled by Chip Select, allows boot on 16-bit non-volatile memory.
The customer-programmed software must perform a complete configuration.
To speed up the boot sequence when booting at 32 kHz EBI CS0 (BMS=0), the user must take
the following steps:
1. Program the PMC (main oscillator enable or bypass mode).
2. Program and start the PLL.
3. Reprogram the SMC setup, cycle, hold, mode timings registers for CS0 to adapt them
to the new clock
4. Switch the main clock to the new value.

liunx学习 太遗憾了,今天才知道这两个网站。

http://www.linux4sam.org/twiki/bin/view/Linux4SAM/WebHome
http://www.timesys.com/
这两个网站是arm开发linux的极佳学习网站。
后悔没有早发现啊。

2008年7月23日星期三

经济学常识 股票是妓女(很好的比喻)

某大机构的一位身经百战的大操盘手,在股市中久经考验,战果辉煌,人品也佳。他酒后戏说股市,文质彬彬,口吐莲花,相当于圣洁的天使翻开魔鬼词典 ,让科班出身的硕士,博士听了绝对一愣:
“什么是股票,股票是妓女。换手率高的就是名妓,换手率低的沾手甩不掉。”
“什么是股民?股民是嫖客;平时省吃俭用却在妓女身上挥金如土。妓女圈钱,心痛也给。”
“什么是券商?券商是拉皮条的;嫖客与妓女勾搭一次,他们抽点拥金。”
“什么是股评家?股评家是老军医。让您猛掏腰包后给您打一针不敢自用,来历不明的青霉素”
同桌喝酒的就有好几位拥有咨询资格的正宗股评家,听了面无赧色,全都畅怀大笑并且群策群力引申下去:
“什么是业绩报告?那是妓女的健康证明,每年公布两回;美国可是每季度一回。”
“什么是炒中期业绩?无非是妓女姿色可餐,艾滋病检测暂时阴性。”
“什么是保留意见?提醒玩股者所玩之股暗疾之所在,对投资人负责。”
“什么是不派息,不送股,不分红?呸!出了嫖资不爽气,居然企盼妓女给您回扣,没门!”
“什么是短线,短线就是一夜情”
“什么是长线,长线等于包二奶!”
“什么是出利空,出利空就是开始扫黄了。”

经济学常识 中国发生经济危机的可能性与对策

为什么多数人不相信会发生危机?
目前,已有越来越多的人开始讨论今后几年中国发生经济危机的可能性,但是仍有更多的人对此置若罔闻,不以为然。究其原因,不是出于无知,就是盲目乐观,或者,干脆就是别有用心,哪怕危机临近的迹象正在日趋明显。危机的潜在性虽然容易被人认识,但是危机的爆发总是源于突发性的偶然事件。只要没有爆发危机,人们在主观上对于危机的潜在因素就往往采取“鸵鸟态度”,危机的预言者反而会被讥讽为耸人听闻;而一旦危机爆发,就意味着社会在一定程度上已经失去控制,这时候每一个经济人的“理性选择”就作鸟兽散,还有谁去总结经验,承认错误,收拾残局?病在肌肤讳疾忌医,病入膏肓又无法医治,这是人类的通病,当权者尤其容易如此。许多人在逻辑上承认潜在危机因素,但总是不愿或不敢相信危机很快就会爆发,或者寄幻想于政府无论在任何情况下都有能力控制局面,或者盲目相信体制改革和技术创新能够最终解决问题。
之所以形成这种盲目乐观的情况是因为:第一,中国人的传统心理喜欢“大团圆”,是“喜鹊文化”;第二,缺乏自由讨论的氛围,宣传上报喜不报忧;第三,学术界脱离实践标准检验,忽视与中国实际接轨,盲目追求“与国际接轨”;第四,20年经济增长造就的迅速但却是难以持续的繁荣给人以幻觉和假象;第五,少数经济学家与权力资本和外国资本结合,获得了特殊地位,在中国“繁荣”(不管是真繁荣还是假繁荣)时可以分享大份额,在危机发生时却不必分担成本。他们乐观得很,并且为中国人民描绘了这样一幅玫瑰色的图案:增长速度就是一切,经济发展可以自动解决一切社会矛盾,中国的高速增长是持续的而不可能中断,甚至连已经出现的萧条也不肯承认。他们不关心国土整治、老龄化、社会保障、贫困人口这些关系多数人生存的基本问题,反而说“改革应该牺牲一代人”;他们标榜经济学的实证原则,但从不去“实证”一下,中国的权力是怎样资本化的?中国的两极分化有多大?他们缺乏中国知识分子传统的社会责任感和草根意识,不仅回避马克思主义的社会阶层分析,也不用西方经济学中最基本的利益分析方法去分析中国改革前后的利益转移和分化。在危机问题上,中国暴富阶层及其代言人的基本态度是:首先否认会发生危机,鼓吹形势大好,以取悦当权者,迷惑社会舆论,引外国投资者上钩;当否认不了时就加以纵容甚至欢迎,他们的逻辑是,既然危机都是旧体制的危机,危机爆发不是好得很吗?当然,前提是危机的代价由老百姓付,而不是由他们和他们的后台老板付。这种“乐观主义”符合暴富阶层麻醉社会保护自己的需要,不仅肤浅,而且令人厌恶。
中国正面临重大危机,我们必须对形势做出实事求是的判断。
  中国危机的逻辑线索:渐进改革的基本矛盾
所谓“危机”,实际上就是事物内部矛盾已经激化到无法自行调整和解决,必须以外部对抗的形式强行解决不可。旧事物总是要瓦解的,但是以爆发重大危机的方式瓦解,社会所受的震动太大,特别是如果旧的秩序突然瓦解,新的秩序又难以产生,就会引起社会最基本最一般秩序的瓦解,人民生命财产将付出巨大的代价,整个社会可能长期陷入动荡和混乱,生产力水平可以倒退数十年。因此比较好的方式,是让积累的矛盾提前释放,将未来的危机“提前引爆”、“分次泄洪”,大事化小,小事化了。这样做的前提,就是确立危机意识,预测危机发生的各种可能性,一方面防范危机突然爆发,一方面化解诱发危机的潜在因素。前提的前提,就是必须对于自己国家所面临的危机的特殊性,在逻辑和历史的统一上,有一个系统的认识,以免头痛医头,脚痛医脚,首尾不能相顾。
渐进改革的成功使我们产生了那种“肤浅的,盲目的乐观主义”,以为渐进改革的基本矛盾可以有效克服,经济的发展可以持续,中国很快就可以进入现代化,甚至赶上美国了。实际上,中国渐进改革有自己最特殊,最基本的内生矛盾——改革过程中权力资本的扩张及其合法性危机。
中国渐进改革的基本特征,是利益转移的隐蔽性。任何改革都是一种利益的转移和再分配,改革与革命不同,它的利益再分配,并不造成社会结构的根本变化,不是由下层推翻和剥夺上层实现的,而是遵循“精英连续性”规律,基本上由那些在计划经济下掌握资源的人,在改革过程中将这些资源变成自己的私人财产,再通过某些政治和社会改革,如“民主改革”,以其据有的资源去换取权力,从而为自己非法获得的利益取得新的合法性。这是一般改革的规律。国外社会学已有文献指出:苏东巨变发生后,那些在计划经济下掌握资源的人虽然在政治和法律上放弃了特权,但仍然在市场经济发展初期占有优势,不光表现在知识、管理、社会联系、信息、能力等方面,尤其重要的是他们在改革前占据了各级经济领导岗位,从而在改革过程中把持了经济资源的支配权,所以多数人可以成为新的企业家、议员,总之,保持了“精英阶层的连续性”而不是断裂。当然,少数平民也可以进入上层,但这是少数,除去科技发明和特殊才能以外,往往是通过与权力系统发生某种关系才有可能,如给领导人作秘书;另一部分人是凭借自己特殊的冒险行为进入的,特别是劳改释放犯那一类没有地位的社会群体。
中国经济改革中的利益转移,亦难逃这一规律。计划经济下我们在名义上建立的“全民所有制”,主要采取了国有或国家控制的方式,而“全民”是通过人民代表大会,将自己的所有权委托给了政府。政府系统则是通过行政体系,通过“官员群体”,实际控制着国有资产以至几乎所有社会资源,比如通过人民公社制度控制粮食生产和农民进城等。在改革以后,这种权力并未崩溃,而是向市场方向扩张,创造出一个“权力与市场相结合的经济”。把权力资本的形成说成是“改革扭曲”,是从市场经济理想出发的说法;说成是“和平演变”,是从计划经济理想出发的说法,都缺乏起码的实证性。权力资本的形成,在中国符合某种客观规律:权力之所以变成资本是因为在计划经济下它无所不包,而在改革中仍然没有受到应有的限制。在大家都没有财产的改革初期,连向银行贷款的抵押物也没有,一般只能通过行政系统担保,各种优惠政策也是行政性的,带有歧视性的特征。行政权力在改革开始甚至起到了市场经济“助产婆”的作用。改革初始,只有权力没有市场;一种办法是使权力崩溃即“休克疗法”,另一种办法是使权力创造市场,即渐进改革。中国改革的设计者认为,使权力靠近市场可以减少改革的阻力,于是选择了渐进改革模式。这种办法在改革初期比休克疗法稳定,没有妨碍经济增长,但是权力的市场化会导致公共权力的腐败,使国有财产向掌权者个人流失。其公平性要差得多,尤其是难以公开和规范化。
权力资本发展,即权力创造市场的第一个阶段,是农村承包土地时,有大约价值20亿人民币的集体财产落入集体干部手中;
第二个阶段是商业资本阶段,80年代初期的发财和腐败途径,来自国内商业、外贸和旅游。大致估计起来,20年内我国国内商品零售总额将近20万亿元人民币,外贸总额折合18万亿人民币,假设有10%的私人提成,共有将近4万亿人民币的财富转移,加上旅游等部分,在商业资本的形成过程中,由国家垄断形成的贸易渠道转变为私人所掌握,大约有5万亿财富转移;
第三个阶段是以生产资料双轨制为标志的生产资本阶段,腐败加剧到直接依靠审批权获得个人好处的程度。90年代初期每年正式的生产资料双轨价差是700亿人民币;五年共3500亿,按10%计有大约350亿的财富转移;
第四个阶段是1992年以后的金融资本阶段。从原始股流失,上市额度分配、证券市场操纵、房地产泡沫、到保险业、基金业、产权交易与重新界定、资产评估、计划利率与黑市利率长期并存,以及贷款权力的使用,每一次金融创新,都伴随着极大的利益再分配,动辄数亿数十亿,非商品层次可比。直至发展到地方以司法权利保护本地债权人,大量的借款不还。以国家信用为担保利用金融手段暴富,正是权力资本发展到金融资本阶段的必然产物,估计财富转移不下于10万亿人民币。
以上所述再加上其他种种以权谋私,如领导人秘书收取贿赂,乱罚款乱收费等等,估计在中国改革转型期20年中,权力资本形成给少数人带来的好处不下于30万亿人民币。目前六万亿居民存款,如果采取实名存款制,不知道有多少“公款私存”无人认领?我国国际收支统计中每年一二百亿美元的“误差与遗漏”,表示出已经有数千亿美元的财富外流。在这种巨额财富的暗地转移下,许多研究报告使用正式统计数字计算居民收入后,竟然说中国没有两极分化!
从逻辑上讲,金融资本形成以后,中国改革的前一半任务“以权力创造市场”就算基本完成,应该开始后一半:权力退出市场,健全平等竞争的市场经济体系。已经形成的既得利益要通过民主化的政治社会改革,以公开化的形式互相制约,形成新的体制。从权力资本化“以权变钱”到民主改革“以钱变权”,是权力社会向市场社会变迁的基本规律,英国贵族的资产阶级化,以及日本明治维新和前苏东改革都有这种特征。中国渐进改革亦逃不脱这一规律,中国的特殊性在于:在我国特有的社会主义意识形态下,这种权力资本化的过程只能采取隐蔽的形式,而且很难在现有政治框架中,找到自己的合法性,因而难以规范。我们无法承认在社会主义全民所有制条件下,可以将全民财产变成个人的,除非改变意识形态本身,但这涉及政治体制与***领导的合法性,决难实行。“姓社姓资”虽然在许多问题上被淡化,但在根本问题上不可能忽略。仅举“三陪”为例,在去年已经蔓延全国,估计从业者不下数百万人,并带动了出租车、高级化妆品、旅游和餐饮等行业,创造的收入和派生收入不少。今年许多城市开始对三陪小姐收税,每人每月200元左右,成为税收重要来源,但是“三陪”还是不能公开合法化。为什么在外国对此可以公开承认并加以规范,在我国就不能?难道不是因为我国是一个社会主义国家吗?如果说,我国的社会主义意识形态连“三陪”都不能承认,难道还能承认权力资本化吗?不能承认的后果是就无法规范,权力资本就难以受到有效的控制而恶性膨胀。从逻辑上讲,这就是中国危机的开始。
  中国危机的历史线索:“分光吃净”
渐进改革的基本矛盾在改革初期被巧妙地回避,这就是“不争论”方针的意义。回避基本矛盾的社会条件是经济的繁荣,繁荣的条件是体制转轨,这是中国经济增长的特殊潜力,并造成了连续20年的高速增长,为我国的社会主义体制提供了新的合法性,掩盖了权力资本扩张的不合法性。经济增长速度从而在中国成为政权合法性所在。
把政权合法性寄托于经济高速增长,特别是寄托于事实上不可持续的特殊增长,本身就造成了危机的隐患。
第一,繁荣过快使得我们忽视去改革计划经济下不平等的社会关系。一是城乡隔离,两种身份制度的社会关系,二是权力高度集中的政治经济体制。在这两种不平等关系上追求经济繁荣,必然加速两极分化。前一种不平等造成了农民购买力低下,在城市耐用消费品饱和以后仍旧不能大批购买,使生产能力闲置超过50%;第二种不平等造成了一般城乡居民购买力低下,即使分期付款也难以承受,住房和汽车的高昂价格,结果使得住宅和汽车的需求主体只能是暴富阶层和有钱单位,他们的奢侈需求把房地产价格越抬越高,直至积压6000万平方米。结构性生产过剩使得经济繁荣不能持续。
第二,繁荣过快使得我们忽视了长期生产力的培养。经济持续增长的一般性因素,包括在提高产出效率的前提下,不断加大投入,如教育、科技、技术改造、设备更新、基础设施等方面的投资,劳动力素质的提高和数量的增加,社会分配公正以提高居民购买力,消费和生产结构的合理升级,以及在经济增长中保护环境,不降低下一代的生存水平,等等;经济持续增长还需要制度性因素,指市场经济规则的建立、法治的完善、决策的科学化和民主化保障、政府的廉洁高效等等。中国20年的特殊繁荣主要是依靠特殊的体制转轨因素,把计划经济40年积累的国力在市场化改革中转换为现实的生产力。对于计划经济时期积累的国力来说,有一个“分光吃净”的问题,一旦积累的潜力释放完毕,经济长期增长的一般因素和制度条件又没有培养出来,经济的增长就不能持续。
第三,我国渐进改革的失误在于,没有利用经济的特殊繁荣期加速深层次体制改革,为新的体制创造合法性,而是“不反思,光给钱;每逢改革必优惠”,想依靠特殊繁荣避免深层次改革,掩盖权力资本化必然导致的合法性危机。等到政府掌握的资源“分光吃净”,经济高速增长不能持续时,中国危机的历史时刻就将来临。
“分光吃净”的第一步是吃财政。计划经济机制是指令性计划加补贴,市场经济是价格机制,改革就是将财政职能逐步向价格转化,财政补贴减少一块,价格水平就相应提高一块, GNP 就增加一块。渐进改革为了缓和社会利益磨擦,农产品一涨价就给城里人发补贴,工业品一涨价又给农民补贴,外贸亏损给出口补贴,新建30亿平方米住宅则完全进入旧体制福利分配,各种补贴大量增加。三年治理整顿期间财政吃光,不得不向市场甩包袱:1990年取消出口补贴形成了外汇市场;1992年取消价格补贴,市场定价达到90%;等到财政难以补贴国有企业时,就实行“卖光”政策。
1978年财政占国民收入的比重是37·2%,1979年中央减政让利提工资,落实政策给补偿,下降到31·9%;经过1985年减税,1987年承包,1988年下降到18·9%,世界银行警告说,如果占不到20%就会发生严重的贪污。1989年以后国有企业虚盈实亏,财政开始连年赤字。1995年以来税收大量增加,但是1998年国内经济进入萧条,国内税收和关税均面临困难,国家又需要加大基础设施投资,加上严重的自然灾害,只有靠国债。国债发行从每年1000亿迅速增加到2000亿,1998年上半年增加2700亿特种国债补偿银行资本金。财政法已经规定地方政府不得发行债券,但是下半年不得不发,估计将以中央政府名义代发特种建设或救灾国债,这样,国债发行在数年之内可能达到饱和。
第二步是吃社会保障基金。中国农村靠的是家庭保障,表现为多生孩子,生儿防老。城市人大约有四项保障:教育补贴与住宅分期付款是自己年轻时先享受,然后再向社会偿还,但是这两项在计划经济下强调“先生产后生活”,支付不足;另外两项是医疗和养老,需要年轻时从劳动成果中预先扣除,等到年老时再消费,这两部分在计划体制下统一扣除变成财政收入,再投资成为国有资产,经过多年的重复建设和国有资产流失,已是所剩无几。五年之内将有3000万老工人下岗或退休,10年之后进入老龄化社会,都面临基本的医疗和养老问题。
第三步,变产业结构。中国在改革开始时是重化工业结构,机电产业是与国际差距最小的。军工转民用生产老四大件效益很高,但是中国人的消费在单位主导和进口刺激下升级太快,从百元级的老四大件到千元级的新四大件,到万元级的豪华装修,到10万元级的汽车、数10万元级的豪华住宅,平均五年一升级,计划经济下建立的庞大三线工业不能适应,只能花费巨额外汇进口或者引进外资生产,结果是消费断层,自身产业结构轻型化,而重化与汽车工业并没有缩小与国际的差距。
第四步,利用对外开放。从封闭经济到开放经济,有国际比较利益可“吃”。20年来我国外贸扩大了20多倍,对外开放度超过30%,比日本的20%、美国的5%要高得多。1998年进出口速度同时下降,我国的对外开放度开始萎缩。引进外资和借外债仍有潜力,但是要看外商信心和国内市场开放程度。相信五年之内,有可能出现外资净流入等于还本付息额的情况,我们只能够借新债还旧债,对外开放的潜力越来越小。
第五步,出售产权。国有企业产权转让,股票上市,资产重组,破产兼并;乡镇企业产权明晰化,在产权交易与明确的过程中可以提高企业效益和税收,同时回收一笔钱。
第六步,转嫁风险。间接融资向直接融资发展,开辟证券股票市场,本质上是将国家银行的风险向社会转移;利率和汇率的市场化,是将政府承担的价格风险向企业和个人转移。转移风险的同时必然减少政府对社会生活的控制,扩大自由度,带来总体风险的分散和社会活力的提高。冒险和赌博本身也是某些人的一种偏好,发挥人的这种潜力可以提高社会总体效率,创造风险收入,表现在政府税收和证券公司的就业和收入等方面。我们在1997年未能有效利用股票市场的筹资功能,等到下半年宣布将国有企业资产重组,上市筹资,结果在经济紧缩、周边动荡、投资信心不足的背景下又成为利空消息,股市可能会出现长期低迷,难以有效利用。
第七步,容忍地下经济。计划经济下由于政府的强控制,地下经济很少。改革以来双重体制并存,地下经济迅速发展;政府机关把相当程度的权力资源投入创收,负作用是社会秩序的混乱和政府的腐败。我们付出了一定程度的社会秩序和政府廉洁与效率的代价,换取了暂时的经济繁荣。
第八步,卖国有荒地。国有的荒山、荒地、矿藏、森林、沙漠、水塘,在改革中正在转向个人承包或者出售使用权,鼓励他们进行长期投资,收到了一定的效果。
以上八项,可以说是体制转轨带来的特殊收益,有些是正当的,有些是不正当的,但都是现实的,能够使经济一时迅速繁荣,但是不能持续增长。
第九步,吃国土环境资源。我国国土资源非常紧张,其中有66万平方公里的城镇国有土地,可以通过拆迁发展房地产业,建立工业开发区。国土的价值是随着经济的发展而增加的,各地政府卖地收入不少,很大一部分级差地租成为单位创收的来源。繁荣时土地价格过高导致出现泡沫,进入萧条后泡沫破灭使银行呆账增加,日本就是在90年代陷入泡沫经济以后步步衰退的。
我国进口的石油已经接近一亿吨,相当于总需求量的1 / 3;粮食、木材、矿砂等资源也需要进口。至于污染、水利、森林等问题,已无需赘言,只要是高投入、低效率,又追求高速度,就不可能不付出资源环境的巨大代价,直至承受不了高速增长。
第十步,吃未来投资。高消费,乱投资,必然要牺牲农业、教育、科技和企业技术改造这样的长期投资,外债需要后代偿还。我国在人口结构尚年轻时没有完成工业化,10年以后进入老龄化社会时,社会负担将大大加重。
以上两步是为了暂时的高速增长而牺牲未来发展的潜力,无论在任何时期、任何体制下都是不应该的,损失应该计算为负增长,从产值中减掉。如此,我国经济的增长率就要大打折扣。
第十一步,吃居民存款。改革多年来,我国以银行贷款代替财政进行国有企业投资,造成国有企业的高负债率和银行的高比例呆帐,在技术上已经接近破产的边缘。1996年银行停止救助国有企业,1997年接受亚洲金融危机教训,金融业开始整顿,进入通货紧缩时期,银行要依靠特种国债来补充资本金。银行是国有的,银行的存款却是居民的,银行依靠的信用和权威在中国主要依靠政府,如果出现金融危机,破产的就不仅仅是银行了。
第十二步,集中耕地。耕地在法律上属于集体所有,在政策上为农民家庭承包,基层政权对耕地的实际支配权表现为乱摊派,相当于过去的地租。在繁荣时期农民进城做工,耕地使用权极不值钱,于是“土地规模经营”之风甚烈,再发展几年必将使大量农民失去土地。一旦经济萧条,需要农民工回乡,将无地可种。我国将彻底失去农村和八亿农民这一化解危机的大蓄水池。非常幸运的是,土地兼并还没有开展起来,我国经济就已经进入萧条,城市为保障下岗工人再就业,开始清退农民工,这使农村土地兼并的势头得到遏制。耕地对农民和社会稳定的重要性再次显现,土地兼并在中国难成气候。
这两步再加上国有资产中包含的应用于老工人的养老保险和公费医疗的那部份,名义上是国家财产和集体财产,实际上是个人财产。如果在经济繁荣中出现对居民个人财产的剥夺,那么社会安定将受到破坏,危机必定出现。
第十三步,吃紧急储备。一旦经济形势紧张时,我国政府手中还有1400亿美元的外汇储备和3000亿斤存粮。一批现代化粮库正准备修建,农民家中仍有存粮,估计可以应付两三年的自然灾害。
第十四步,依靠政府信誉与权威。党和政府的组织动员能力虽然削弱,但是还比较强,这是目前金融稳定的最大保障。货币是信用,而信用是由政府威信和法律保障的。
这最后两步,是政府的物质力量和精神权威所在,也是防范金融危机,控制危机发展的最后力量。危机因素的积累会削弱政府权威,危机一旦爆发则说明政府已经难以控制,但是危机爆发以后又需要政府去控制,此时就会出现政府的变动。
估计五年之后,上述资源大部分将被“吃光分净”,经济增长将因特殊潜力用尽而一般潜力不能有效发挥,制度因素又不能保障市场有效运转而不能持续。此时,权力资本的合法性危机就将暴露,触发危机的偶然因素亦将出现:
——权力资本将因为不能规范而恶性膨胀,大肆吞食社会资本和个人财产。不仅腐败蔓延,权力资本有组织的剥夺将更加严重。比如乱收费,比如在拆迁中不对私房的土地使用权给以足够的补偿,收取电话初装费和手提电话入网费却不明确给予所有权,以及在住宅价格中打入市政配套费,但市政设施产权却归政府所有等等。
——在货币紧缩情况下权力资本的恶性膨胀,会比通货膨胀的情况下更加打击社会生产力,打击中小民间资本。如果不依靠权力就不能挣钱,民间投资就萎缩下去。
——外汇管制失效。从外部冲击来说,国际投机资本是否能造成崩溃性的冲击,取决于能否在短时期内掌握受冲击国家的大量货币。人民币资本帐户不自由兑换,有效地防止了国际资本的不稳定性投机。但外商投资企业的人民币利润越来越多,有90%没有汇出,而是留在中国进行再投资。这笔外商在中国国内的债权在五年之后会达到10000亿人民币,相当于我们国家在海外的债权(国家外汇储备)。其中有相当一部分没有真正购买生产资料,而是留在流通和投机领域,流动性很强。国际投机者通过香港也可以掌握一部分人民币。如果出现突发事件,外商丧失信心,普遍要求将人民币利润兑换成外汇汇出,会引起国家储备严重下降,即可能引起居民普遍提取人民币,通过各种渠道兑换外汇。限制或者停止外商将利润汇出也只能延缓一年,因为新的外资会因此不来。这是五年之后国际资本冲击中国的特殊形式,也是我国危机可能的爆发点。
  中国危机的外部因素:亚洲金融危机冲击
对中国危机的逻辑和历史分析表明,危机的发生指向“五年左右”,对此我们可以预先防范。防范危机如同防洪,也有两种办法,洪峰不大可筑堤挡水;如果预测洪峰很大,就应该以疏导为主,甚至要决堤放水,将灾害引导到损失较小的一个方向去。笔者认为中国未来的危机难以避免,只能采取“提前引爆”的办法,将一个大危机化解为许多小危机,随时出现,随时解决。现在多数人的倾向是低估危机的性质和程度,以为可以通过刺激内需和加强整顿而轻易地避免危机;渐进改革的基本矛盾及一系列派生矛盾不能被系统地研究和承认,而是受到强行压制。亚洲金融危机的爆发,使我们能够提前认识东亚模式的弊病;危机的滞后影响则暴露了我国危机的潜在因素,促使我们早日解决。危机迟早要来,早来比晚来好,因为现在我们毕竟还没有完全“分光吃净”。从避免危机的角度来看,中国既面临历史性的危机,也遇到了历史性的幸运。
历史的幸运开始于五年之前,当时亚洲正处于繁荣的高峰,中国的权力资本发展到金融资本阶段,暴富层次升级,社会财富以极不合理的方式剧烈再分配。此时,世界上有两个地区主动收缩经济,贬值汇率,一个是欧洲各国为了出欧元而消除赤字和通货膨胀,一个是中国控制通货膨胀和泡沫经济。关于中国收缩经济,当时有很大争议,有人提出通货膨胀可以和经济同步增长,有人说中国没有泡沫经济,权力金融资本集团更因财路被断而极力反对。1993年7月1日开始的金融整顿,刚刚稳定了汇率,制止了炒地皮,到10月份就因国有企业生产负增长,被迫增加货币发行。1994年《人民日报》元旦社论竟然以“加快发展,加快改革”为题,等于宣布宏观调控结束。但是三个月以后,中央又出台了“二十字方针”,以保持稳定为核心,重新坚持经济收缩。这次政策转换非常奇怪,因为当时并没有什么特殊事件发生。虽然“软着陆”政策在1997年出现某些失误,比如对形势的分析过于乐观,没有能够及时启动经济,对股票市场打击过严而利用不够等,但五年以来收缩经济的基本战略是正确的,它使中国在1997年没有卷入亚洲金融危机,并有力量保持人民币汇率坚挺而发挥稳定作用。一年以来,是人民币,港币和美元三种货币的坚挺,发挥了亚洲和国际关键货币的作用,抵御了国际金融危机的蔓延,形成了中美协调稳定亚洲经济的局面。中国人国际地位的提高,不是通过与西方对抗,而是在关键时刻能够稳定经济和汇率,发挥了世界性的良好影响。这对于未来世界格局和中国如何发挥大国作用都是非常好的开端和启示。如果没有提前收缩和整顿,中国自顾不暇,何来力量去稳定亚洲?
金融危机在1997年7月2日自泰国开始,横扫东南亚,波及韩国,给香港造成长期的萧条和不稳定;1998年5月在日本公开暴露,日元长期疲软,预计在1999年将继续连带亚洲甚至美国,全球金融崩溃和经济大萧条也不是没有可能。由于中国已经提前收缩经济,并在1994年将人民币贬值50%,在五年之内保持了贸易和资本项目的巨额双顺差,到1997年底积累了1400亿美元的外汇储备,东南亚各国正是在这几年出现了巨额外贸逆差。由于连续数年的经济紧缩,国内消费物价指数从21·7%下降到0·8%。人民币名义汇率没有变动,但是实际汇率贬值了。由于亚洲国家的货币在1997年的贬值,使人民币实际有效汇率升值6%左右,至1998年5月份,亚洲各国汇率有所回升,局势已经初步稳定下来;从5月份开始日元贬值,如果能够控制在20%的幅度以内,并连带亚洲各国货币贬值15%,使人民币实际有效汇率再升值6%,两年共升值10%。但是国内消费物价指数两年之内下降了14个百分点,人民币实际汇率同时贬值14个百分点,两者基本抵消,加上出口退税的鼓励,我国出口并不十分悲观。
1997年中国出口增加了20%以上,外贸顺差468亿美元,创历史最高峰。1998年出口增长率可能在5~10%,但是贸易顺差上半年即达到267亿美元,全年不会少于300亿美元。出口增长率下降,但是进口增长率下降更大,这是因为国内需求疲软,新的投资集中于基础设施和住宅,难以带动进口。这样,中国的净出口并不会下降,加上资本项目顺差,国际收支可望保持400亿美元以上顺差。顺差下出现严重的人民币贬值预期,说明国内外对我国经济前景信心不足,企业和个人大批保留外汇,不去结汇,使国家外汇储备几乎没有增长。外汇储备只能调节外汇市场变化的增量部分,而不能解决基础性的失衡,有1400亿美元也差不多了。中央货币当局可以减少外汇占款,增加国内货币投放的空间,中国由此调整出口导向战略,转向扩大国内需求,正好顺势而行。
出口增长率下降包括水灾对于中国的真正影响,在于降低国内经济增长速度。为什么一定要达到8%?经济学家说是为了保证就业,维持信心。经济增长速度在国际上本来是一个预测数字,到了我国竟然不可更改,不可怀疑,因与现实反差太大,反而被强化到国内外人人谈论的程度。这也证明,经济增长速度长期以来已成为我国政权合法性的主要源泉。这当然是非常危险的一件事,因为亚洲金融危机的滞后影响,将继续在全球范围造成通货紧缩,经济下滑,资产缩水,收入下降,失业增加,保护主义盛行和货币连锁贬值,中国已经并且将继续受到影响。
亚洲各国经济进入负增长,首先影响中国的出口和外资。1998年上半年国内企业效益普遍下滑,使股价在夏季下跌了30%,投资者损失惨重;消费与投资不振,是因为通货膨胀率的下降超过了名义利率降低的速度,以致出现改革以来最高水平的实际利率;深化改革、整顿金融业和证券市场、精简政府机构、清除腐败等一系列非常必要的措施中的多数会产生紧缩效果,使就业和收入下降。比较有效的调节办法是发行国债,扩大基础设施投资,问题是难以回收资金,财政的困难还会加大。通货紧缩一旦发生就难以短期走出来,日本走了十年没有出路,我们不可把问题是看得太简单了。
更加严重的问题就在日本。日本的经济规模比中国大六倍,世界扶植不起日本,日本却能够拖累全世界。日元贬值如果超过1:150,将连带韩国和台湾的货币贬值,人民币与港币的处境将更为困难。许多人责怪日本和美国政府纵容日元贬值,认为只要联合干预,日元就可以稳定;而且认为美日一定会干预,因为日元贬值不符合两国利益。这又是一种“肤浅的乐观论”。
日本的贸易收支有巨额顺差,货币应该升值,这是教科书上说的。实际上,日本经济多年萧条,为刺激经济利率已经接近于零,资本大批外流;国际货币市场上,外汇经纪人不看好日本经济前景,卖日元买美元,日元如何不跌?日本政府当然不希望日元过度贬值,但是日本的决策权究竟在谁手里?有没有类似“权力资本”之类的政治经济势力?近百年来的财阀势力对日本政治究竟有多大支配力?会不会为了集团的利益而牺牲国家利益?日本政府公布了投资巨款启动内需的计划,但是效果不大,目前正在清理呆帐,将于9月份公布。如何处理还要经过国会辩论,但执政的自民党政府在参议院不占多数,最后能否通过有效办法将决定日元的走势,局势的明朗至少要到98年底。美国的战略利益又在哪里?为什么美国能够容忍日本对美巨额贸易顺差而纵容日元贬值?有没有等到日本经济继续恶化,资产大幅缩水后再来收购,从而打垮日本根深蒂固的经济民族主义的考虑?这些都需要各学科的综合研究,不是单纯的经济模型和数字能够回答的。
我们所看到的“东亚模式”成功与失败的因素,只不过是冰山一角。比如对于美国的扶植和操纵就估计不足。东亚成功的国际背景,在政治上是美国的冷战战略。如果美国不为日本负担军费,日本经济这几十年的高速增长就会降低40%;日本两次外汇短缺,是靠韩战和越战期间为美国生产军事物资解决的;美国可以容忍日本对美国产品20%的高关税,难道不是扶植日本,反而是怕它不成?东亚各国所谓“专制下的政治稳定”实际上也是由美国扶植的,当失去稳定时,美国就会迫使政权更换,如马科斯和苏加诺。一旦冷战结束,美国的亚洲战略就变成促进自由化,亚洲各国的动荡就开始了。
东亚奇迹的经济背景是西方发达国家的产业结构转换。20年来,美国和欧洲淘汰了占国内市场20%的劳动密集型和高污染产业,为东亚国家的“出口导向”提供了市场,并刺激其外向型经济过度发展。中国大陆和香港、台湾的关系也是如此。一旦西方产业结构调整完毕,发展中国家必然出现生产过剩危机。中国的得天独厚之处是有农村市场,所以只是长期萧条,不过将出口产品内销,要承担亏损而已。
以日本危机为核心的第二次亚洲货币金融危机,可能长期持续并拖累亚洲和全球经济,近期日元保持1:150不再贬值,极为关键。危机的另一个爆发点在香港,国际资本将反复冲击香港,港币能否保持联系汇率并不贬值难以预料。这两个因素将构成对中国最大的外部冲击。前景很难令人乐观。
中国经济的前景将在很大程度上受国际因素左右,在经济方面是美国经济与股市及美元的走势、欧元的出台、美英金融资本对国际金融市场的控制,美国大公司对世界粮食市场的控制等等,如果明年出现全球金融市场崩溃,连带世界性经济大萧条,中国亦会受到更大的影响;
在政治方面是国际战略格局的调整,中美关系、中日关系、包括台湾问题都是变数,***势力的发展随时可能造成突发事件。危机的内外因素是互相影响的,在内部危机因素日趋严重时,尤其要妥善处理外部矛盾,以免形成互相放大的恶性效果。
克服危机的根本对策
本文对于中国面临危机的性质,做出以下概括:
第一,这次危机的内在必然性,是由渐进改革的基本矛盾决定的。权力资本在中国发展的历史任务已经完成,由于与我国特有的社会主义意识形态存在根本矛盾而不能取得合法性,因而无法加以规范。权力资本的恶性膨胀,是中国危机的主要根源。
第二,体制转轨所造成的特殊繁荣,为改革和政权带来了新的合法性,在一定时期内掩盖了权力资本的不合法性,并且拖延了政治和社会改革,使得经济长期增长的一般性因素不能充分发挥,体制性因素亦没有培养出来,经济高速增长不可避免地出现历史性的中断,从而使得渐进改革的基本矛盾暴露出来。
第三,按照危机内在因素的发展和社会控制危机的能力,特别是我国体制转轨潜力的释放程度,和政府掌握资源的状况来推算,中国的经济危机将在五年左右到来。但是亚洲金融危机的爆发,加重了我国通货紧缩的局面,提前结束了经济高速增长,从而将促使危机提前出现。这对于中国,既是历史性的危机,也是历史性的幸运。因为目前政府仍有较强的控制能力,还掌握一定的资源,特别是土地还在农民手里,还有克服危机的能力。
第四,危机涉及三个层次:
——社会政治结构层面,是权力资本的恶性膨胀;
——真实经济层面,包括产业结构改造、国有企业改革等多方面问题;
——货币经济层面,危机最容易爆发。汇市、楼市、股市是连带的,很可能由于突发事件的出现导致信心崩溃,外商撤资,资本外逃,挤兑与抢购外汇,连带整体性危机的爆发。
第五,克服危机的本质,是通过全面改革、全面整顿,在经济高速增长之外,为我国社会主义政权确立新的合法性。克服危机的对策,必须要超过经济的范围,涉及一系列深层次的根本性改革。
根本性的反危机措施,大约有以下几个方面:
第一,确立危机和反危机意识。为此需要广开言路。机构改革旨在提高政府执行能力,而决策的科学化民主化,则需要通过全国人大系统。建议在全国人大设立公开的政策论坛,对重大政策进行公开的、经常性的辩论。集中各学科各部门力量,对中国的反危机问题进行综合研究。
第二,以水灾为契机,调整过高的经济增长目标。人民币汇率应该继续保持稳定,但是要公开向国际表明,稳定人民币汇率的条件是日元不能过分贬值。争取与美国,日本共同协调经济政策,稳定亚洲经济局势。如果美国与日本不能尽全力,或者干预无效,中国亦不应独自承受亚洲金融危机的压力。要准备做更大幅度的调整。
第三,反腐败要有突破性进展,可以考虑实行实名存款制等更加有效的办法,力争以比较小的成本,将腐败比较彻底地清除,将金融机构、证券市场、评估机构、司法机构等迅速规范。
第四,调整经济发展战略。不仅要从出口导向向扩大内需转变,从速度型向效益型转变,而且要检讨赶超西方的总战略。要考虑到中国的资源,文化和法制环境,重新设计21世纪的经济发展战略。以一整套经济社会发展指标代替单一的经济增长速度指标。
第五,参考历史经验,切实解决农民的土地问题。可以考虑耕地所有权为村社共有,使用权由农民所有并可以流转。应该成立农会,健全基层民主,切实保证农民的政治经济地位,这是保持中国社会稳定和消化危机的最坚实基础。
第六,承认工人的历史贡献,将部分国有资产转化为社会所有制的社会保障基金,由人民代表大会和工会联合监督,聘请专家经营。在五年之内需要有一万亿元社会保障基金加入股市,平均每年2000亿,可以带动股市转为强势。更重要的是,社会财富的公平分配,可以比单纯的经济增长更加鼓舞人民的信心,改善预期。社会财富分配向中下层的倾斜可以有效地扭转内需下滑的趋势。
第七,坚决让权力退出市场。党政军机构停止经商,加速产权改革,转变政府职能,发展经济的职能由企业自身承担,政府集中力量建设良好的投资环境。目前出现的“权力出租”现象更为恶劣,主办单位与公司表面脱钩,实际上收取利润,却又不对公司的不法行为负责,有人戏称之为“坐台小姐与夜总会老板的关系”,必须坚决使权力机构与公司彻底脱钩。
第八,加快社会主义民主和法治建设,积极推进政治体制改革,意识形态要有创造性的发展,使之对改革以来的新的社会利益格局具备足够的解释力和规范力。
第九,在有效清除腐败以后,应重新规划并大规模整治国土,以数十万转业军人组织千万民工,兴修水利,建设中小城镇。重复建设的,耗资巨大的,为少数特殊阶层服务的项目,一律撤消,集中财力于基础建设。劳动积累是中国农民的特殊优势,成本很低,且关系到中华民族的长远发展,真正的困难不在于资金和技术,而在于政府还有没有这样的组织动员能力。农民通过劳动积累增加了收入,才可以购买工业产品,减少城市工人下岗。
第十,鼓励社会组织、民间组织和个体经济的发展,提高整个社会对于危机的抵抗能力和自组织能力。
危机,是旧体制向新体制过渡受到阻碍时难以避免的现象,反危机并不是维护旧体制,而是主动加速改革,以减少危机的破坏力。旧体制是一定会瓦解的,但是我们没有权利任其自然腐朽和崩溃,而采取一种“为了改革而不惜一切代价”的态度,尤其不能让老百姓付出过多的代价,而让权力资本在危机过程中继续获得暴利。因此,正确的反危机在本质上要维持社会总体稳定,维护全中国大多数人民的基本利益。在反危机的过程中,纠正经济改革的偏差,促进全面改革,真正建设符合中国国情的、为大多数人而不是只为少数暴富阶层的现代化

经济学常识 经济危机的原因、特征和表现

产生经济危机原因
经济危机可能是如下原因引起的:
★经济政策错误
★原材料紧张,尤其是原油危机
★自然灾害
★全球化的后果
★金融政策错误
经济危机的特征:
经济危机是生产过剩的危机。但是,经济危机所表现出来的生产过剩,不是生产的绝对过剩,而是一种相对的过剩,即相对于劳动群众有支付能力的需求而言表现为过剩的经济危机。因此,在经济危机爆发时,一方面资本家的货物堆积如山,卖不出去;另一方面,广大劳动群众却处于失业或半失业状态,因购买力下降而得不到必需的生活资料。
经济危机的主要表现:
经济危机的现象,在第二次世界大战以前和战后有所不同。但共同点是:
商品滞销,利润减少,导致生产(主要是工业生产)急剧下降,失业大量增加,企业开工不足并大批倒闭,生产力和产品遭到严重的破坏和损失,社会经济陷入瘫痪、混乱和倒退状态。
生产下降和失业激增,是战前与战后经济危机的共同的主要标志。
战前与战后不同之处,主要是在货币、金融危机方面。
在战前的危机中,一般是通货紧缩,物价下跌,银根吃紧,利率上升,银行挤兑并大批倒闭;而在战后的危机中,由于国家垄断资本主义采取膨胀政策以及其他原因,从1957~1958年的世界性经济危机开始,各主要资本主义国家在危机期间都出现了通货膨胀、物价上涨的反常现象。   主要表现是:商品大量过剩,销售停滞;生产大幅度下降,企业开工不足甚至倒闭,失业工人剧增;企业资金周转不灵,银根紧缺,利率上升,信用制度受到严重破坏,银行纷纷宣布破产等。   但是,第二次世界大战以后,由于国家垄断资本主义采取了通货膨胀政策及其他措施,致使各主要资本主义国家在经济危机中出现了生产停滞与通货膨胀同时并存的现象。

经济学常识 什么是经济危机

经济危机(Economic Crisis)指的是一个或多个国民经济或整个世界经济在一段比较长的时间内不断收缩(负的经济增长率)。是资本主义经济发展过程中周期爆发的生产过剩的危机 。是经济周期中的决定性阶段。自1825年英国第一次爆发普遍的经济危机以来,资本主义经济从未摆脱过经济危机的冲击。
经济危机是资本主义体制的必然结果。由于资本主义的特性,其爆发也是存在一定的规律。
经济危机是指经济系统没有产生足够的消费价值。也就是生产能力过剩的危机。有的学者把经济危机分为被动型危机与主动型危机两种类型。
所谓被动型经济危机是指该国宏观经济管理当局在没有准备的情况下出现经济的严重衰退或大幅度的货币贬值从而引发金融危机进而演化为经济危机的情况。如果危机的性质属于这种被动型的,很难认为这种货币在危机之后还会回升,危机过程实际上是对该国货币价值重新寻求和确认的过程。
所谓主动型经济危机是指宏观经济管理当局为了达到某种目的采取的政策行为的结果。危机的产生完全在管理当局的预料之中,危机或经济衰退可以视作为改革的机会成本。

经济学常识 美国应对三十年代经济危机的对策

1933年3月4日,富兰克林·德兰诺·罗斯福就任美国第三十二届总统。罗斯福应对危机的一系列政策后来被称作“新政”(NewDeal),其核心是三个R:改革(Reform)、复兴(Recovery)和救济(Relief)。
罗斯福的“新政”并非一时的权宜之计,而是一场为保证资本主义制度的稳定发展,在资本主义经济肌体内部进行的一场“伤筋动骨”的大手术。
罗斯福的“新政”处方先从整顿金融入手。在就职后的第三天,即1933年3月6日,罗斯福宣布全国银行“休假”,这是他所采取的重建银行和经济结构的第一步。3月9日,国会通过《紧急银行法令》,对银行采取个别审查、颁发许可证制度,对有偿付能力的银行,允许尽快复业。13日至15日,全国绝大多数银行经过财政部审核,在政府监督下,分批陆续恢复营业。罗斯福对惊魂不定的美国人民说:“我向你们保证,把你们的钱存入重新开业的银行比藏在床褥下更为保险。”6月16日,国会通过了《1933年银行法》,建立由联邦承担责任的联邦储备体系。由于采取了这些措施,银行信用很快恢复,银行存款在不到一年的时间里增加了近20亿美元!
在整顿农业方面,从1933年5月开始,新设立的农业调整管理局着手开展了一场雷厉风行的行动,在春夏两季有计划地犁掉了大约1000万英亩棉田,收购和屠宰了大约20多万头即将临产的母猪和600多万头小猪,几千万头牛和羊。物缺则贵的无情法则发生了作用。随着农业生产的下降,加上1933—1934年遭到严重旱灾,农产品价格开始回升。从1932年到1936年农业总收入增加了50%,出售农产品的现金收入(包括政府补贴)几乎翻了一番。保持平价的比例从1932年的55%上升到1936年的90%。
1933年春天,罗斯福政府制定了旨在整顿工业的《全国产业复兴法》,其内容共分两部分:第一部分的宗旨是订立可免受托拉斯法案限制的公平竞争规约;第二部分提出要成立“公共工程署”,并为此拨款33亿美元。罗斯福称之为“向工业界提出的艰巨任务”。7月又提出订立“一揽子规约”的想法,规定如愿意合作的雇主应保证遵守全国复兴总署规定的最低工资和最高工时的标准。200万雇主接受了“一揽子规约”,并在企业门口悬挂以印第安人的雷鸟为蓝本而设计的蓝鹰徽———服从规约的标志。
在“新政”中,“救济”是一个主要方面。在进行直接救济的同时,更主要的方面是以工代赈。罗斯福上任后从一开始就倾注了极大的力量兴办大规模的公共工程,以扩大政府开支来弥补私人投资下降而出现的空白,并解决部分就业问题。1935年4月28日,罗斯福正式宣布工赈计划,明确规定对有工作能力的失业者不发放救济金,而是帮助其通过参加不同的劳动获得工资。
“新政”功过众说纷纭 “新政”刚一推出,就引起美国社会上下的普遍关注,不同政治集团对其给予了不同的评价。罗斯福的坚决反对者、报业大王赫斯特说“新政”就是苛政(RawDeal);不是榨取富人(SoaktheRich),而是榨取成功者(SoaktheSuccessful)。美国著名新闻记者、作家约翰·根室说他所听到的关于“新政”的最好定义,是说“那是一些没有骨气的自由派为了那些失魂落魄的资本家而去拯救资本主义的一种企图”。另外还有人谴责“新政”是披上自由主义外衣的法西斯主义。
美国经济学家对“新政”有两派意见,一派认为“新政”在鼓舞私人企业的信心方面没有成功,资本主义秩序成功的基本条件是鼓舞企业家的创业精神,而诱发这种精神就需要刺激和补偿,“新政”的一些措施是抑制这种精神的。另一派是凯恩斯及其追随者或半追随者,他们认为,只有真正执行大胆的增大开支的赤字政策,才能使国民经济走上复兴的轨道,而罗斯福在这一点上做得还不够。
罗斯福“新政”是20世纪资本主义发展历程中的重大事件,帮助美国的资本主义制度度过了1929—1933年的一场空前大灾难。美国的资本主义制度得救了,世界资本主义体系也缓过气来了。这就使得“新政”能够在美国历史和世界历史中获得一席之地 因为当时美国是世界上第一经济大国,所以很多贸易,商业都和美国有联系,关联。而且欧洲刚发生完第一次世界大战(虽说以是10年后,但还是没有恢复好的),所以很多方面都得倚仗美国经济资助,如贷款等。后来美国经济危机,使美国自己的经济都崩溃了,这样的话欧洲必然会在经济上有所波动 那场经济危机是资本主义世界的经济危机。资本主义经济是相互联系相互影响的经济模式,它不同于封建社会的闭塞的自给自足的自然经济。资本主义各国经济之间的互补互利性很大,所以美国的经济危机也会波及到欧洲,甚至整个资本主义世界.

2008年7月21日星期一

wince学习 pb5.0启动错误"No primary processors are avaible",然后new project时,它提示没有能用的BSPs

学习地址:http://topic.csdn.net/t/20061226/18/5257679.html#
问题描述:
以前机子上装过pb5.0,那会都可以用的.但后来把机子还原到安装pb5.0之前的状态时,由于我的pb不是装在系统盘,所以我想看看pb是不是还能用,启动了pb后.
pb会提示: "No primary processors are avaibile. The build system will be disabled. It is likely that a build system 'add-on' processor (.pkg),installed by setup, failed to load".
点确定后又弹出: "The selected configuration does not have an installed debugger. You cannot debug this configuration.",
然后点确定后,pb倒是可以启动,但在new platform (即project时),
pb会提示: "The platform Wizard could not locate any valid BSPs. Check that your catalog contains BSP entries and verify that cec files for any BSP entries are correct".
然后可以看到的确是没有Available BSPs.
这是系统还原后的错误,而我在编译时出错,后来就卸载掉PB,然后再重新安装。其错误是一摸一样的。
郁闷啊。
试试下面的方法:
After reinstalling Microsoft Platform Builder 5.0 could happen that you get the following errors: "No primary processors are available. The build system will be disabled. "The selected configuration does not have an installed debugger. You cannot debug this configuration." This is probably caused by a re-install bug in PB, especially if you picked a different install directory.
Please try this:
* Uninstall PB
* Look in the registry under HKEY_LOCAL_MACHINE\Software\Microsoft\PlatformBuilder
* and look in the registry under HKEY_CURRENT_USER\Software\Microsoft\PlatformBuilder
* Delete the 5.0 registry keys.
They should have been removed by the uninstall but weren't
* Reinstall PB After uninstalling your previous version, make sure you go through the registry and delete all the keys that were created by the PB (under HKLM AND HKCU\Software\MSPB\*).
=======================================
If even you get the following different error System.TypeInitializationException: "The type initializer for "System.Xml.Schema.XsdBuilder" threw an exception The workspace could not be loaded.
* Download an updated version of .NET Framework Version 1.1 Redistributable Package.
* Remove the existing version of .NET Framework
* Install the new version of .NET Framework

2008年7月13日星期日

wince学习 WinCE流驱动知识

学习地址:http://space.fyqt.net/index.php/uid-125144-action-viewspace-itemid-10125
1、基础知识:
1)系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件细节,在应用程序看来硬件只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。设备驱动是内核的一部分。
2)驱动程序完成以下功能:
——对设备初始化和释放;
——把数据从内核传送到硬件和从硬件读取数据;
——读取应用程序传送给设备文件的数据和回送应用程序请求的数据;
——检测和处理设备出现的错误。
3)上层应用程序运行在用户模式(非特权模式,Ring 3),代码被严格约束执行。如不能执行硬件IO指令。所有的这些被阻止的操作如果想运行必须通过陷阱门来请求操作系统内核。
4)操作系统内核运行在内核模式(特权模式,Ring 0),可以执行所有有效的CPU指令。包括IO操作,可访问任何内存区。
5)整个硬件系统资源在驱动程序面前是赤裸裸的,驱动可以使用所有系统资源,编写驱动程序时我们必须格外小心驱动代码的边界条件,确保它们不会损坏整个操作系统。
2、Windows支持的驱动:
1)虚拟设备驱动程序(Virtual Device Driver):Windows3.1(Windows95/98/Me)
2)内核模式驱动程序(Kernel Mode Driver):Windows NT
3)Win32驱动程序模型(Win32 Driver Mode):从Windows98开始使用。
其中WDM是目前主流,然而在WinCE系统中,由于硬件资源有限和嵌入式系统的特点,对其的支持非常有限。
3、WinCE系统驱动简介:
1)WinCE毕竟是一个嵌入式系统,有其自身的特殊性,为了提高运行效率,所有驱动皆为动态链接库,驱动实现中可以调用所有标准的API。而在其他Windows系统中可能的驱动文件还有.vxd, .sys和动态链接库。
2)WinCE驱动从结构上讲分为本地驱动(Native Driver)和流接口驱动(Stream Driver)。
——本地驱动主要用于低级、内置的设备。实现它们的接口并不统一,而是针对不同类型的设备相应设计。因此开发过程相对复杂,没有固定的模式,一般做法是通过移植、定制现有的驱动样例来实现。
——流接口驱动是最基本的一种驱动结构,它的接口是一组固定的流接口函数,具有很高的通用性,WinCE的所有驱动程序都可以通过这种方式来实现。流接口驱动程序通过文件系统调用从设备管理器和应用程序接收命令。该驱动程序封装了将这些命令转换为它所控制的设备上的适当操作所需的全部信息。
流接口驱动是动态链接库,由一个叫做设备管理程序的特殊应用程序加载、管理和卸载。与本地驱动程序相比,所有流接口驱动程序使用同一组接口函数集,包括实现函数:XXX_Init、XXX_Deinit、XXX_Open、XXX_Close、XXX_Read、XXX_Write、XXX_PowerUp、XXX_PowerDown、XXX_Seek、XXX_IOControl,这些函数与硬件打交道。用户函数:CreateFile、DeviceIoControl、 ReadFile、 WriteFile,这些函数方便用户使用驱动程序。
3)WinCE下驱动的加载方式:
——通过GWES(Graphics, Windowing, and Events Subsystem):主要加载与显示和输入有关的驱动,如鼠标、键盘驱动等。这些驱动一般为本地驱动。
——通过设备管理器:两种结构的驱动都加载,加载的本地驱动主要由PCMCIA Host Controller,USB Host Controller driver,主要是总线类的驱动;流接口驱动主要有音频驱动,串并口驱动。
——动态加载:前两者都是系统启动时加载的,动态加载则允许设备挂载上系统时将驱动调入内核,主要有外接板卡驱动,USB设备驱动等。
4、流接口驱动函数介绍:
1)DWORD XXX_Init(LPCTSTR pContext, LPCVOID lpvBusContext);
pContext:指向一个字符串,包含注册表中该流接口活动键值的路径
lpvBusContext:此参数是被处理过的一个指针数据,由函数ActiveDeviceEx 的第四参数lpvParam传递而来(若该对应的驱动由ActiveDeviceEx 调用而加载则lpvBusContext被传递过来,否则为0)
该函数是驱动挂载后第一个被执行的。主要负责完成对设备的初始化操作和驱动的安全性检查。由ActiveDeviceEx通过设备管理器调用。其返回值一般是一个数据结构指针,作为函数参数传递给其他流接口函数。

2)BOOL XXX_Deinit(DWORD hDeviceContext);
hDeviceContext:XXX_Init的返回值。
整个驱动中最后执行。用来停止和卸载设备。由DeactivateDevice触发设备管理器调用。成功返回TRUE。

3)DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode , DWORD ShareMode);
hDeviceContext:XXX_Init的返回值。
AccessCode:访问模式标志,读、写或其他。
ShareMode:驱动的共享方式标志。
打开设备,为后面的操作初始化数据就够,准备相应的资源。应用程序通过CreateFile函数间接调用之。返回一个结构指针,用于区分哪个应用程序调用了驱动,这个值还作为参数传递给其他接口函数XXX_Read、XXX_Write、XXX_Seek、XXX_IOControl。
4)BOOL XXX_Close(DWORD hOpenContext);
hOpenContext:XXX_Open返回值。
关闭设备,释放资源。由CloseHandle函数间接调用。

5)DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open返回值。
pBuffer:缓冲区指针,接收数据。
Count:缓冲区长度。
由ReadFile函数间接调用,用来读取设备上的数据。返回读取的实际数据字节数。

6)DWORD XXX_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count);
hOpenContext:XXX_Open返回值。
pBuffer:缓冲区指针,接收数据。
Count:缓冲区长度。
由WriteFile函数间接调用,把数据写到设备上,返回实际写入的数据数。

7)BOOL XXX_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
hOpenContext:XXX_Open返回值。
dwCode:控制命令字。
pdwActualOut:实际输出数据长度。
用于向设备发送命令,应用程序通过DeviceIoControl调用来实现该功能。要调用这个接口还需要在应用层和驱动之间建立一套相同的命令,通过宏定义CTL_CODE(DeviceType, Function, Method, Access来实现。如:
#define IOCTL_INIT_PORTS \ CTL_CODE(FILE_DEVICE_UNKNOWN,0X801,METHOD_BUFFERED,FILE_ANY_ACCESS)

8)void XXX_PowerDown(DWORD hDeviceContext);
hDeviceContext:XXX_Init的返回值。
负责设备的上电控制。

9)void XXX_PowerUp(DWORD hDeviceContext);
hDeviceContext:XXX_Init的返回值。
负责设备的断电控制

10)DWORD IOC_Seek(DWORD hOpenContext, long Amount, WORD Type)
hOpenContext:XXX_Open返回值。
Amount:指针的偏移量。
Type:指针的偏移方式。
将设备的数据指针指向特定的位置,应用程序通过SetFilePointer函数间接调用。不是所有设备的属性上都支持这项功能。

5、流接口驱动的加载和注册表设置:
系统启动时启动设备管理程序,设备管理程序读取HKEY_LOCAL_MACHINE\Drivers\BuiltIn键的内容并加载已列出的流接口驱动程序。因此注册表对于驱动的加载有着关键作用。下面是一个例子:
【HKEY_LOCAL_MACHINE\Drivers\BuiltI\IOControler】
“Prefix”=”XXX”
“Dll”=”drivername.dll”
其中,“Prefix”=“XXX”中的XXX要和XXX_Init等函数中的一样。CreateFile创建的驱动名前缀也必须和它们一致。
6、驱动程序的编写、编译及其相关目录、配置文件的格式和修改:
1)首先必须在PB相应平台的的driver目录下建立要创建的驱动所在的目录。如在x:\Wince420\platform\smdk2410\drivers目录下建立一个IOCtrol目录。
2)修改Drivers目录下的dirs文件。
3)创建驱动源文件XXX.c,在该文件中实现上述流接口函数。并且加入DLL入口函数:
BOOL DllEntry(HINSTANCE hinstDll, /*@parm Instance pointer. */
DWORD dwReason, /*@parm Reason routine is called. */
LPVOID lpReserved /*@parm system parameter. */
)
4)创建Makefile和Sources和.def文件,控制编译。
5)使用CEC Editor修改cec文件,编译添加的新特性。

wince学习 wince6.0体系机构

Windows CE采用了典型的分层结构。
在Windows CE 5.0的文档中,微软公司将其分为四个层次,从下到上依次为:
硬件层;
OEM层;
操作系统层;
应用程序层。
而在Windows Embedded CE 6.0中却划分为User Mode(用户模式)和Kernel Mode(内核模式)两个“层”,CoreDLL等DLL同时出现在两个层中,驱动程序也可以被加入到内核中,以前的.exe可执行模块基本上都变成了.dll。体系结构的变化相对较大。
Windows Embedded CE 6.0的体系结构如下图所示。

回顾一下Windows CE 5.0是如何将各个模块结合在一起的,它被设计成一种围绕服务而存在的用户模式的进程,叫做PSLs(Process Server Libraries,进程服务库),NK.exe在内核态下运行,而操作系统的其他部分则各自独立地运行在用户模式下,比如文件系统Filesys.exe、图形窗口和事情子系统GWES.exe、驱动管理器Device.exe。这样分开的设计让操作系统更加健壮,但这些为整个操作系统提供主要功能的服务提供者却是以不同进程的身份出现,如果要使用某操作系统提供的服务,则会使得至少发生一次的进程切换,就连一个简单的函数调用都不例外。这对系统的效率影响是比较大的。
而Windows Embedded CE 6.0却不同,它将所有系统需要提供的服务部分“转移”到系统内核的虚拟机(Kernel’s Virtual Machine),这样做的好处是当发生系统调用时,已经变成了进程内的一个调用。这样做也引入了一些不稳定机制,比如驱动程序被加入到内核,Windows Embedded CE 6.0默认情况下就是将驱动运行在内核模式。虽然提高了系统的效率,但如果驱动程序不稳定,将对系统的整体稳定性产生非常严重的影响,这也是我们所不愿意看到的。当然,并不是所有的驱动程序都是在内核运行的,在Windows Embedded CE 6.0安装完成之后的驱动程序是在用户模式下运行的,这样更有利于系统的安全,但以牺牲设备的性能为代价。下图展示了Windows Embedded CE 6.0里的系统模块。

通过上图大家会发觉,以前在Windows CE 5.0中的各种系统模块,比如Filesys.exe、Device.exe、GWES.exe等,都变成了Filesys.dll、GWES.dll、Device.dll,只有NK.exe还是原来的名字,变的不仅仅是名字,因为在Windows Embedded CE 6.0中这些服务已经不再是一个个单独进程,而是一个个系统调用。虽然NK.exe的名字没有变,但已经不再是Windows CE 5.0中的NK.exe了,Windows CE 5.0中NK.exe提供的各种功能将由Kernel.dll来替代,NK.exe中仅仅包含一些OAL代码和保证兼容性的程序,这样做的好处是使得OEMs和ISVs厂商定制的代码和微软提供的Windows Embedded CE 6.0的代码进行了分离,使得内核代码的升级更加容易且更加方便。
以上可以看出,系统的架构变化是比较大的,这对Windows CE的二次开发厂商来说并不是什么好消息,因为这意味着很多建立在老版本上的驱动必须进行很大规模的重新设计,但微软公司告诉他们这个过程是非常简单的,因为微软公司设计了一个补救措施,这就是图3-7中处在内核模式的一个有着古怪名字的DLL——K.Coredll.dll,名字与K.Coredll.dll非常相似,事实上它就是为了模拟K.Coredll.dll,K.Coredll.dll仍然在用户模式下运行,当内核模式下的代码调用某些在Windows CE 5.0处于用户模式下而在Windows Embedded CE 6.0中已经转移到内核模式下的API时,K.Coredll.dll则会把这个调用请求转向内核模式中相应的dll。K.Coredll.dll并不是唯一有这种机制的DLL,其他的DLL只要需要,也可以采用这种策略。

wince学习 wince6.0特性

学习地址:http://develop.csai.cn/ebd/200804071140511186.htm
Windows Embedded CE 6.0
在早期版本的Windows CE中,微软公司都是沿用Windows CE+版本号的方式来命名,而到了6.0版本,微软公司却将名称定为Windows Embedded CE 6.0。

最新的Windows Embedded CE 6.0是Visual Studio .NET的一个插件,当你安装上这个插件后,就可以从事相关的开发。在Windows CE以前的版本,定制一个Windows CE需要使用Platform Builder,开发一个Windows CE的应用程序需要使用Embedded Visual C++或者Embedded Visual Basic,而在CE 6.0里,您只需要一个安装有Platform Builder for CE 6.0插件的Visual Studio .NET 2005便可以完成。
Windows CE各版本相应的开发工具请参观表3-1。
Windows CE版本 定制工具 应用程序开发工具
… … … … … …
4.0 Platform Builder 4.0 Embedded Visual C++ 4.0
Visual Studio .NET 2003
4.1 Platform Builder 4.1 Embedded Visual C++ 4.0
Visual Studio .NET 2003
4.2 Platform Builder 4.2 Embedded Visual C++ 4.0
Visual Studio .NET 2003
5.0 Platform Builder 5.0 Embedded Visual C++ 4.0 + SP4
Visual Studio .NET 2003
Visual Studio .NET 2005
6.0 Platform Builder for CE 6.0(Visual Studio .NET 2005插件)
Embedded Visual C++ 4.0 + SP4
Visual Studio .NET 2003
Visual Studio .NET 2005 + SP1

Windows Embedded CE 6.0相对于Windows CE 5.0有很大改进。下面,让我们来看看Windows Embedded CE 6.0相对于Windows CE 5.0的一些改进。
1.同时运行进程数上升到32000个。在Windows CE 5.0及其以前版本的Windows CE嵌入式操作系统里,能同时运行的进程数仅为32个,这其中还包括系统进程,也就是说,除去的NK.exe(提供系统服务)、Filesys.exe(提供对象存储等服务)这两个必需的系统进程,还有Gwes.exe(提供图形界面GUI支持)、Device.exe(提供加载和管理设备驱动服务)、Service.exe(提供服务管理服务)、Explorer.exe(提供窗口管理服务)这几个比较常用的进程外,系统可用的进程数目只有26个,也就是说,最多能够同时加载26个非系统进程,虽然对于大多数嵌入式设备来说已经够用,但是,并不代表所有的情况下都够用,尤其是在网络和分布式计算环境下,这就更显得捉襟见肘了。但在Windows Embedded CE 6.0里,32000个进程让你几乎不用考虑进程数的限制问题。
2.每个进程拥有2GB的虚拟内存。Windows CE是一个保护模式的嵌入式操作系统。因此程序对内存的访问只能通过虚拟地址实现。另外我们知道Windows CE是一个32位的嵌入式操作系统,所以它就有了232(4GB)的虚拟空间地址,这又被分为两部分,其中一半是内核空间,另外一半是用户空间,在Windows CE 5.0中,用户空间又被分为64份(每份32MB),每一份叫一个Slot,每个进程只能有一个Slot,即每个进程只能有32MB的虚拟内存。在Windows Embedded CE 6.0中采用了新的储存机制,使得每个进程可以使用最大2GB的虚拟内存。也正是这个原因,才有下面这个改进。
3.移除了共享内存空间。在以前版本的Windows CE中进程有32MB虚拟内存的限制,为了解决这一问题,提出了共享内存空间(Shared Memory Area)这一概念,即定义了一个共享内存空间,在这一区域所有进程都可以进行共享,这一区域大约有350MB。但在Windows Embedded CE 6.0中每个进程2GB的虚拟内存空间使得这一区域完全没有必要存在,所以在Windows Embedded CE 6.0中移除了这个“区域”。
4.开发工具也有大变化。一直以来Windows CE的平台订制工具都是Platform Builder,伴随着Windows CE版本的演进,Platform Builder也发展到了5.0版,但在Windows Embedded CE 6.0中,Platform Builder已经不是一个单独发行的工具,在Windows CE 6.0的程序菜单里,已经没有Platform Builder的启动菜单,Platform Builder for CE 6.0是Visual Studio .NET 2005的一个插件。而且如果是进行Windows Embedded CE 6.0的开发,微软公司会为您免费提供Visual Studio .NET 2005 Professional Edition。
5.内核态与用户态意义的转变。在新的系统中的这两个概念已经与以前版本的Windows CE中有所不同,很多Windows CE 5.0中处于用户态的进程和模块被调到了Windows Embedded CE6.0的内核态,在第3.2节中将会对这一变化进行更详细的介绍。
6.提供了对VoIP支持。Windows CE 5.0及其早期版本使用TUI(Telephone User Interface)来管理与话音通信有关的服务,而在Windows Embedded CE 6.0中使用IP Phone Suit来加入了对VoIP的支持,使得ISVs(Independent Software Vendor,独立软件开发商)和OEMs(Original Equipment Manufacturer,原始设备制造商)能够在针对VoIP业务进行定制时具有更多的灵活性和更少的工作量。
7.100%共享Windows Embedded CE 6.0内核源代码。在Windows CE 3.0中,微软共享了其中400K行源代码。在Windows CE 5.0中微软公司共享了其核心源代码的近70%,而到Windows Embedded CE 6.0这一百分比被提升到了100%,不过,用微软公司所使用的术语准确地讲应该是Shared Source,可以在下面的网址上找到微软的共享政策http://msdn2.microsoft.com/en-us/embedded/aa714518.aspx,OEMs和ISVs厂商可以对源代码进行修改并保留(保密)自己的修改,但Windows Embedded CE 6.0与嵌入式Linux之间的开源是不同的概念,Linux的开源相对要彻底得多,不论是开发工具还是应用软件,基本都可以找到开源的产品或者替代品,但Windows Embedded CE 6.0只是开放了核心源代码,与之相关的开发工具和应用软件并不是免费和共享源代码的。不过总体来讲,这仍然为广大OEMs和ISVs厂商选择Windows Embedded CE 6.0作为自己的嵌入式操作系统增加了一个理由。
8.功能更强大的模拟器。Windows CE 5.0时代的模拟器只能模拟X86框架的CPU,对于其他框架(如Scale等)并不能很好地再现实际环境,但Windows Embedded CE 6.0的模拟器解决了这一问题,当然,模拟器无论是启动速度还是资源占用情况都有一定的上升,推荐运行模拟器的开发机最好能有1GB的物理内存。
以上是几个比较突出的改进,微软公司公布了Windows Embedded CE 6.0的64个新的改进。
可以通过下面的网址查看Windows Embedded CE 6.0的所有更新:
http://msdn2.microsoft.com/en-us/library/aa924105.aspx
改进内容 描述
程序兼容性工具 利用这个工具,你能够检查你的DLL是否使用了已经废弃的APIs
BIB和REG文件查看器 提供对Platform Builder生成的用于定制Windows Embedded CE 6.0的*.bib和*.reg文件的查看和编辑

改进内容 描 述
Catalog视图 增加了Platform Builder for Windows Embedded CE 6.0的新功能,提供了对诸如文件类型和图标等其他的管理功能。
CellCore 主要提供了对无线通信的支持,这包括RIL、SMS、WAP、扩展TAPI和TSP、SIM卡支持等
ExFAT 新的文件系统解决了很多以前FAT文件系统的限制。比如最大文件2GB的限制。ExFAT将整体性管理所有外部存储器
增加和删除了多个APIs 伴随着新的存储管理机制和内核改变,产生和去掉了多个APIs
BSP 增加了Intel PXA27x处理器相关的开发包、SDP2420开发板支持、TI OMAP5912开发板支持。更新了NEC Solution Gear 2-Vr5500和Renesas US7750R(Aspen)SDB相关的BSP
用户模式 驱动框架 让驱动程序可以运行在用户模式下
WMM Wi-Fi MultiMedia让不同的应用程序可以共享网络资料
DRM 10 提供了对Windows Media DRM 10的支持
… … … … … …
另外,值得一提的是,Windows Embedded CE 6.0提供了对.NET Compact Framework 2.0的支持,还支持Win32、MFC、ATL、WTL、STL等程序开发。基本上支持了很完整的软件开发环境。

2008年7月12日星期六

wince学习 eboot解析

eboot是wince的bootloader一种(redboot也是一种)。
它的主要作用:引导wince操作系统。
a、直接从CF卡引导
b、直接从flash(nor、nand)引导。
c、当然还可从其他方式引导,例如USB,IDE等,但是前提是eboot能够驱动这些设备,并能够从其中读出NK。
现在一般的eboot的主要组成部分及其作用:
1、CPU的初始化(设置时钟,设置运行环境)
2、SDRAM初始化(为运行eboot和下载等做准备)
3、NorFlash初始化(为从NorFlash启动模式,将NK存储在NorFlash做准备)
4、网络初始化(为下载NK到Flash做准备)
5、IDE初始化(为从IDE启动做准备)
6、PCMCIA初始化(为从CF卡启动做准备)
7、FAT文件系统初始化(为IDE和CF卡启动能正确的识别FAT文件系统)
安装完BSP包后,一般能在platform/yourplatform/src下找到一个BootLoader的文件夹。
它保含了生成eboot的全部文件,包括makefile,source等文件。

学习笔记 很好的一个制作MP3的学习网站

学习地址:http://www.robs-projects.com/filelib.html
有硬件制作
MP3播放器源码,
FAT32驱动,
很值得学习。

学习笔记 Microsoft FAT32 specification

Hardware White Paper
Designing Hardware for Microsoft® Operating Systems
Microsoft Extensible Firmware Initiative FAT32 File System Specification
FAT: General Overview of On-Disk Format

Version 1.03, December 6, 2000Microsoft Corporation


The FAT (File Allocation Table) file system has its origins in the late 1970s and early1980s and was the file system supported by the Microsoft® MS-DOS® operating system. It was originally developed as a simple file system suitable for floppy disk drives less than 500K in size. Over time it has been enhanced to support larger and larger media. Currently there are three FAT file system types: FAT12, FAT16 and FAT32. The basic difference in these FAT sub types, and the reason for the names, is the size, in bits, of the entries in the actual FAT structure on the disk. There are 12 bits in a FAT12 FAT entry, 16 bits in a FAT16 FAT entry and 32 bits in a FAT32 FAT entry.

Contents
Notational Conventions in this Document 7
General Comments (Applicable to FAT File System All Types) 7
Boot Sector and BPB. 7
FAT Data Structure. 13
FAT Type Determination. 14
FAT Volume Initialization. 19
FAT32 FSInfo Sector Structure and Backup Boot Sector 21
FAT Directory Structure. 22
FAT Long Directory Entries. 25
Name Limits and Character Sets. 29
Name Matching In Short & Long Names. 30
Naming Conventions and Long Names. 30
Effect of Long Directory Entries on Down Level Versions of FAT. 32
Validating The Contents of a Directory. 32
Other Notes Relating to FAT Directories. 33

Microsoft, MS_DOS, Windows, and Windows NT are trademarks or registered trademarks of Microsoft Corporation in the United States and/or other countries. Other product and company names mentioned herein may be the trademarks of their respective owners.
© 2000 Microsoft Corporation. All rights reserved.

Microsoft Extensible Firmware Initiative FAT32 File System Specification

IMPORTANT-READ CAREFULLY: This Microsoft Agreement (“Agreement”) is a legal agreement between you (either an individual or a single entity) and Microsoft Corporation (“Microsoft”) for the version of the Microsoft specification identified above which you are about to download (“Specification”). BY DOWNLOADING, COPYING OR OTHERWISE USING THE SPECIFICATION, YOU AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, DO NOT DOWNLOAD, COPY, OR USE THE SPECIFICATION.

The Specification is owned by Microsoft or its suppliers and is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties.

1. LIMITED LICENSE AND COVENANT NOT TO SUE.

(a) Provided that you comply with all terms and conditions of this Agreement and subject to the limitations in Sections 1(c) - (f) below, Microsoft grants to you the following non-exclusive, worldwide, royalty-free, non-transferable, non-sublicenseable license under any copyrights owned or licensable by Microsoft without payment of consideration to unaffiliated third parties, to reproduce the Specification solely for the purposes of creating portions of products which comply with the Specification in unmodified form.

(b) Provided that you comply with all terms and conditions of this Agreement and subject to the limitations in Sections 1(c) - (f) below, Microsoft grants to you the following non-exclusive, worldwide, royalty-free, non-transferable, non-sublicenseable, reciprocal limited covenant not to sue under its Necessary Claims solely to make, have made, use, import, and directly and indirectly, offer to sell, sell and otherwise distribute and dispose of portions of products which comply with the Specification in unmodified form.
For purposes of sections (a) and (b) above, the Specification is “unmodified” if there are no changes, additions or extensions to the Specification, and “Necessary Claims” means claims of a patent or patent application which are (1) owned or licenseable by Microsoft without payment of consideration to an unaffiliated third party; and (2) have an effective filing date on or before December 31, 2010, that must be infringed in order to make a portion(s) of a product that complies with the Specification. Necessary Claims does not include claims relating to semiconductor manufacturing technology or microprocessor circuits or claims not required to be infringed in complying with the Specification (even if in the same patent as Necessary Claims).

(c) The foregoing covenant not to sue shall not extend to any part or function of a product which (i) is not required to comply with the Specification in unmodified form, or (ii) to which there was a commercially reasonable alternative to infringing a Necessary Claim.
(d) Each of the license and the covenant not to sue described above shall be unavailable to you and shall terminate immediately if you or any of your Affiliates (collectively “Covenantee Party”) “Initiates” any action for patent infringement against: (x) Microsoft or any of its Affiliates (collectively “Granting Party”), (y) any customers or distributors of the Granting Party, or other recipients of a covenant not to sue with respect to the Specification from the Granting Party (“Covenantees”); or (z) any customers or distributors of Covenantees (all parties identified in (y) and (z) collectively referred to as “Customers”), which action is based on a conformant implementation of the Specification. As used herein, “Affiliate” means any entity which directly or indirectly controls, is controlled by, or is under common control with a party; and control shall mean the power, whether direct or indirect, to direct or cause the direction of the management or policies of any entity whether through the ownership of voting securities, by contract or otherwise. “Initiates” means that a Covenantee Party is the first (as between the Granting Party and the Covenantee Party) to file or institute any legal or administrative claim or action for patent infringement against the Granting Party or any of the Customers. “Initiates” includes any situation in which a Covenantee Party files or initiates a legal or administrative claim or action for patent infringement solely as a counterclaim or equivalent in response to a Granting Party first filing or instituting a legal or administrative patent infringement claim against such Covenantee Party.

(e) Each of the license and the covenant not to sue described above shall not extend to your use of any portion of the Specification for any purpose other than (a) to create portions of an operating system (i) only as necessary to adapt such operating system so that it can directly interact with a firmware implementation of the Extensible Firmware Initiative Specification v. 1.0 (“EFI Specification”); (ii) only as necessary to emulate an implementation of the EFI Specification; and (b) to create firmware, applications, utilities and/or drivers that will be used and/or licensed for only the following purposes: (i) to install, repair and maintain hardware, firmware and portions of operating system software which are utilized in the boot process; (ii) to provide to an operating system runtime services that are specified in the EFI Specification; (iii) to diagnose and correct failures in the hardware, firmware or operating system software; (iv) to query for identification of a computer system (whether by serial numbers, asset tags, user or otherwise); (v) to perform inventory of a computer system; and (vi) to manufacture, install and setup any hardware, firmware or operating system software.

(f) Microsoft reserves all other rights it may have in the Specification and any intellectual property therein. The furnishing of this document does not give you any license or covenant not to sue with respect to any other Microsoft patents, trademarks, copyrights or other intellectual property rights.

2. ADDITIONAL LIMITATIONS AND OBLIGATIONS.
(a)The foregoing license and covenant not to sue is applicable only to the version of the Specification which you are about to download. It does not apply to any additional versions of or extensions to the Specification.
(b)Without prejudice to any other rights, Microsoft may terminate this Agreement if you fail to comply with the terms and conditions of this Agreement. In such event you must destroy all copies of the Specification.

3. INTELLECTUAL PROPERTY RIGHTS. All ownership, title and intellectual property rights in and to the Specification are owned by Microsoft or its suppliers.

4. U.S. GOVERNMENT RIGHTS. Any Specification provided to the U.S. Government pursuant to solicitations issued on or after December 1, 1995 is provided with the commercial rights and restrictions described elsewhere herein. Any Specification provided to the U.S. Government pursuant to solicitations issued prior to December 1, 1995 is provided with RESTRICTED RIGHTS as provided for in FAR, 48 CFR 52.227-14 (JUNE 1987) or DFAR, 48 CFR 252.227-7013 (OCT 1988), as applicable.

5. EXPORT RESTRICTIONS. Export of the Specification, any part thereof, or any process or service that is the direct product of the Specification (the foregoing collectively referred to as the “Restricted Components”) from the United States is regulated by the Export Administration Regulations (EAR, 15 CFR 730-744) of the U.S. Commerce Department, Bureau of Export Administration (“BXA”). You agree to comply with the EAR in the export or re-export of the Restricted Components (i) to any country to which the U.S. has embargoed or restricted the export of goods or services, which currently include, but are not necessarily limited to Cuba, Iran, Iraq, Libya, North Korea, Sudan, Syria and the Federal Republic of Yugoslavia (including Serbia, but not Montenegro), or to any national of any such country, wherever located, who intends to transmit or transport the Restricted Components back to such country; (ii) to any person or entity who you know or have reason to know will utilize the Restricted Components in the design, development or production of nuclear, chemical or biological weapons; or (iii) to any person or entity who has been prohibited from participating in U.S. export transactions by any federal agency of the U.S. government. You warrant and represent that neither the BXA nor any other U.S. federal agency has suspended, revoked or denied your export privileges. For additional information see http://www.microsoft.com/exporting.

6. DISCLAIMER OF WARRANTIES. To the maximum extent permitted by applicable law, Microsoft and its suppliers provide the Specification (and all intellectual property therein) and any (if any) support services related to the Specification (“Support Services”) AS IS AND WITH ALL FAULTS, and hereby disclaim all warranties and conditions, either express, implied or statutory, including, but not limited to, any (if any) implied warranties or conditions of merchantability, of fitness for a particular purpose, of lack of viruses, of accuracy or completeness of responses, of results, and of lack of negligence or lack of workmanlike effort, all with regard to the Specification, any intellectual property therein and the provision of or failure to provide Support Services. ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT, WITH REGARD TO THE SPECIFICATION AND ANY INTELLECTUAL PROPERTY THEREIN. THE ENTIRE RISK AS TO THE QUALITY OF OR ARISING OUT OF USE OR PERFORMANCE OF THE SPECIFICATION, ANY INTELLECTUAL PROPERTY THEREIN, AND SUPPORT SERVICES, IF ANY, REMAINS WITH YOU.

7. EXCLUSION OF INCIDENTAL, CONSEQUENTIAL AND CERTAIN OTHER DAMAGES. To the maximum extent permitted by applicable law, in no event shall Microsoft or its suppliers be liable for any special, incidental, indirect, or consequential damages whatsoever (including, but not limited to, damages for loss of profits or confidential or other information, for business interruption, for personal injury, for loss of privacy, for failure to meet any duty including of good faith or of reasonable care, for negligence, and for any other pecuniary or other loss whatsoever) arising out of or in any way related to the use of or inability to use the SPECIFICATION, ANY INTELLECTUAL PROPERTY THEREIN, the provision of or failure to provide Support Services, or otherwise under or in connection with any provision of this AGREEMENT, even in the event of the fault, tort (including negligence), strict liability, breach of contract or breach of warranty of Microsoft or any supplier, and even if Microsoft or any supplier has been advised of the possibility of such damages.

8. LIMITATION OF LIABILITY AND REMEDIES. Notwithstanding any damages that you might incur for any reason whatsoever (including, without limitation, all damages referenced above and all direct or general damages), the entire liability of Microsoft and any of its suppliers under any provision of this Agreement and your exclusive remedy for all of the foregoing shall be limited to the greater of the amount actually paid by you for the Specification or U.S.$5.00. The foregoing limitations, exclusions and disclaimers shall apply to the maximum extent permitted by applicable law, even if any remedy fails its essential purpose.

9. APPLICABLE LAW. If you acquired this Specification in the United States, this Agreement is governed by the laws of the State of Washington. If you acquired this Specification in Canada, unless expressly prohibited by local law, this Agreement is governed by the laws in force in the Province of Ontario, Canada; and, in respect of any dispute which may arise hereunder, you consent to the jurisdiction of the federal and provincial courts sitting in Toronto, Ontario. If this Specification was acquired outside the United States, then local law may apply.

10.QUESTIONS. Should you have any questions concerning this Agreement, or if you desire to contact Microsoft for any reason, please contact the Microsoft subsidiary serving your country, or write: Microsoft Sales Information Center/One Microsoft Way/Redmond, WA 98052-6399.

11.ENTIRE AGREEMENT. This Agreement is the entire agreement between you and Microsoft relating to the Specification and the Support Services (if any) and they supersede all prior or contemporaneous oral or written communications, proposals and representations with respect to the Specification or any other subject matter covered by this Agreement. To the extent the terms of any Microsoft policies or programs for Support Services conflict with the terms of this Agreement, the terms of this Agreement shall control.

Si vous avez acquis votre produit Microsoft au CANADA, la garantie limitée suivante vous concerne :

RENONCIATION AUX GARANTIES. Dans toute la mesure permise par la législation en vigueur, Microsoft et ses fournisseurs fournissent la Specification (et à toute propriété intellectuelle dans celle-ci) et tous (selon le cas) les services d’assistance liés à la Specification (“Services d’assistance”) TELS QUELS ET AVEC TOUS LEURS DÉFAUTS, et par les présentes excluent toute garantie ou condition, expresse ou implicite, légale ou conventionnelle, écrite ou verbale, y compris, mais sans limitation, toute (selon le cas) garantie ou condition implicite ou légale de qualité marchande, de conformité à un usage particulier, d’absence de virus, d’exactitude et d’intégralité des réponses, de résultats, d’efforts techniques et professionnels et d’absence de négligence, le tout relativement à la Specification, à toute propriété intellectuelle dans celle-ci et à la prestation ou à la non-prestation des Services d’assistance. DE PLUS, IL N’Y A AUCUNE GARANTIE ET CONDITION DE TITRE, DE JOUISSANCE PAISIBLE, DE POSSESSION PAISIBLE, DE SIMILARITÉ À LA DESCRIPTION ET D’ABSENCE DE CONTREFAÇON RELATIVEMENT À LA SPÉCIFICATION ET À TOUTE PROPRIÉTÉ INTELLECTUELLE DANS CELLE-CI. VOUS SUPPORTEZ TOUS LES RISQUES DÉCOULANT DE L’UTILISATION ET DE LA PERFORMANCE DE LA SPÉCIFICATION ET DE TOUTE PROPRIÉTÉ INTELLECTUELLE DANS CELLE-CI ET CEUX DÉCOULANT DES SERVICES D’ASSISTANCE (S’IL Y A LIEU).

EXCLUSION DES DOMMAGES INDIRECTS, ACCESSOIRES ET AUTRES. Dans toute la mesure permise par la législation en vigueur, Microsoft et ses fournisseurs ne sont en aucun cas responsables de tout dommage spécial, indirect, accessoire, moral ou exemplaire quel qu’il soit (y compris, mais sans limitation, les dommages entraînés par la perte de bénéfices ou la perte d’information confidentielle ou autre, l’interruption des affaires, les préjudices corporels, la perte de confidentialité, le défaut de remplir toute obligation y compris les obligations de bonne foi et de diligence raisonnable, la négligence et toute autre perte pécuniaire ou autre perte de quelque nature que ce soit) découlant de, ou de toute autre manière lié à, l’utilisation ou l’impossibilité d’utiliser la Spécification, toute propriété intellectuelle dans celle-ci, la prestation ou la non-prestation des Services d’assistance ou autrement en vertu de ou relativement à toute disposition de cette convention, que ce soit en cas de faute, de délit (y compris la négligence), de responsabilité stricte, de manquement à un contrat ou de manquement à une garantie de Microsoft ou de l’un de ses fournisseurs, et ce, même si Microsoft ou l’un de ses fournisseurs a été avisé de la possibilité de tels dommages.

LIMITATION DE RESPONSABILITÉ ET RECOURS. Malgré tout dommage que vous pourriez encourir pour quelque raison que ce soit (y compris, mais sans limitation, tous les dommages mentionnés ci-dessus et tous les dommages directs et généraux), la seule responsabilité de Microsoft et de ses fournisseurs en vertu de toute disposition de cette convention et votre unique recours en regard de tout ce qui précède sont limités au plus élevé des montants suivants: soit (a) le montant que vous avez payé pour la Spécification, soit (b) un montant équivalant à cinq dollars U.S. (5,00 $ U.S.). Les limitations, exclusions et renonciations ci-dessus s’appliquent dans toute la mesure permise par la législation en vigueur, et ce même si leur application a pour effet de priver un recours de son essence.

DROITS LIMITÉS DU GOUVERNEMENT AMÉRICAIN
Tout Produit Logiciel fourni au gouvernement américain conformément à des demandes émises le ou après le 1er décembre 1995 est offert avec les restrictions et droits commerciaux décrits ailleurs dans la présente convention. Tout Produit Logiciel fourni au gouvernement américain conformément à des demandes émises avant le 1er décembre 1995 est offert avec des DROITS LIMITÉS tels que prévus dans le FAR, 48CFR 52.227-14 (juin 1987) ou dans le FAR, 48CFR 252.227-7013 (octobre 1988), tels qu’applicables.
Sauf lorsqu’expressément prohibé par la législation locale, la présente convention est régie par les lois en vigueur dans la province d’Ontario, Canada. Pour tout différend qui pourrait découler des présentes, vous acceptez la compétence des tribunaux fédéraux et provinciaux siégeant à Toronto, Ontario.

Si vous avez des questions concernant cette convention ou si vous désirez communiquer avec Microsoft pour quelque raison que ce soit, veuillez contacter la succursale Microsoft desservant votre pays, ou écrire à: Microsoft Sales Information Center, One Microsoft Way, Redmond, Washington 98052-6399.




Notational Conventions in this Document

Numbers that have the characters “0x” at the beginning of them are hexadecimal (base 16) numbers.

Any numbers that do not have the characters “0x” at the beginning are decimal (base 10) numbers.

The code fragments in this document are written in the ‘C’ programming language. Strict typing and syntax are not adhered to.

There are several code fragments in this document that freely mix 32-bit and 16-bit data elements. It is assumed that you are a programmer who understands how to properly type such operations so that data is not lost due to truncation of 32-bit values to 16-bit values. Also take note that all data types are UNSIGNED. Do not do FAT computations with signed integer types, because the computations will be wrong on some FAT volumes.

General Comments (Applicable to FAT File System All Types)
All of the FAT file systems were originally developed for the IBM PC machine architecture. The importance of this is that FAT file system on disk data structure is all “little endian.” If we look at one 32-bit FAT entry stored on disk as a series of four 8-bit bytes—the first being byte[0] and the last being byte[4]—here is where the 32 bits numbered 00 through 31 are (00 being the least significant bit):

byte[3] 3 3 2 2 2 2 2 2
1 0 9 8 7 6 5 4

byte[2] 2 2 2 2 1 1 1 1
3 2 1 0 9 8 7 6

byte[1] 1 1 1 1 1 1 0 0
5 4 3 2 1 0 9 8

byte[0] 0 0 0 0 0 0 0 0
7 6 5 4 3 2 1 0

This is important if your machine is a “big endian” machine, because you will have to translate between big and little endian as you move data to and from the disk.

A FAT file system volume is composed of four basic regions, which are laid out in this order on the volume:
0 – Reserved Region
1 – FAT Region
2 – Root Directory Region (doesn’t exist on FAT32 volumes)
3 – File and Directory Data Region

Boot Sector and BPB
The first important data structure on a FAT volume is called the BPB (BIOS Parameter Block), which is located in the first sector of the volume in the Reserved Region. This sector is sometimes called the “boot sector” or the “reserved sector” or the “0th sector,” but the important fact is simply that it is the first sector of the volume.

This is the first thing about the FAT file system that sometimes causes confusion. In MS-DOS version 1.x, there was not a BPB in the boot sector. In this first version of the FAT file system, there were only two different formats, the one for single-sided and the one for double-sided 360K 5.25-inch floppy disks. The determination of which type was on the disk was done by looking at the first byte of the FAT (the low 8 bits of FAT[0]).

This type of media determination was superseded in MS-DOS version 2.x by putting a BPB in the boot sector, and the old style of media determination (done by looking at the first byte of the FAT) was no longer supported. All FAT volumes must have a BPB in the boot sector.

This brings us to the second point of confusion relating to FAT volume determination: What exactly does a BPB look like? The BPB in the boot sector defined for MS-DOS 2.x only allowed for a FAT volume with strictly less than 65,536 sectors (32 MB worth of 512-byte sectors). This limitation was due to the fact that the “total sectors” field was only a 16-bit field. This limitation was addressed by MS-DOS 3.x, where the BPB was modified to include a new 32-bit field for the total sectors value.

The next BPB change occurred with the Microsoft Windows 95 operating system, specifically OEM Service Release 2 (OSR2), where the FAT32 type was introduced. FAT16 was limited by the maximum size of the FAT and the maximum valid cluster size to no more than a 2 GB volume if the disk had 512-byte sectors. FAT32 addressed this limitation on the amount of disk space that one FAT volume could occupy so that disks larger than 2 GB only had to have one partition defined.

The FAT32 BPB exactly matches the FAT12/FAT16 BPB up to and including the BPB_TotSec32 field. They differ starting at offset 36, depending on whether the media type is FAT12/FAT16 or FAT32 (see discussion below for determining FAT type). The relevant point here is that the BPB in the boot sector of a FAT volume should always be one that has all of the new BPB fields for either the FAT12/FAT16 or FAT32 BPB type. Doing it this way ensures the maximum compatibility of the FAT volume and ensures that all FAT file system drivers will understand and support the volume properly, because it always contains all of the currently defined fields.

NOTE: In the following description, all the fields whose names start with BPB_ are part of the BPB. All the fields whose names start with BS_ are part of the boot sector and not really part of the BPB. The following shows the start of sector 0 of a FAT volume, which contains the BPB:

Boot Sector and BPB Structure
Name
Offset (byte)
Size (bytes)
Description
BS_jmpBoot
0
3
Jump instruction to boot code. This field has two allowed forms:
jmpBoot[0] = 0xEB, jmpBoot[1] = 0x??, jmpBoot[2] = 0x90
and
jmpBoot[0] = 0xE9, jmpBoot[1] = 0x??, jmpBoot[2] = 0x??

0x?? indicates that any 8-bit value is allowed in that byte. What this forms is a three-byte Intel x86 unconditional branch (jump) instruction that jumps to the start of the operating system bootstrap code. This code typically occupies the rest of sector 0 of the volume following the BPB and possibly other sectors. Either of these forms is acceptable. JmpBoot[0] = 0xEB is the more frequently used format.
BS_OEMName
3
8
“MSWIN4.1” There are many misconceptions about this field. It is only a name string. Microsoft operating systems don’t pay any attention to this field. Some FAT drivers do. This is the reason that the indicated string, “MSWIN4.1”, is the recommended setting, because it is the setting least likely to cause compatibility problems. If you want to put something else in here, that is your option, but the result may be that some FAT drivers might not recognize the volume. Typically this is some indication of what system formatted the volume.
BPB_BytsPerSec
11
2
Count of bytes per sector. This value may take on only the following values: 512, 1024, 2048 or 4096. If maximum compatibility with old implementations is desired, only the value 512 should be used. There is a lot of FAT code in the world that is basically “hard wired” to 512 bytes per sector and doesn’t bother to check this field to make sure it is 512. Microsoft operating systems will properly support 1024, 2048, and 4096.

Note: Do not misinterpret these statements about maximum compatibility. If the media being recorded has a physical sector size N, you must use N and this must still be less than or equal to 4096. Maximum compatibility is achieved by only using media with specific sector sizes.
BPB_SecPerClus
13
1
Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. Note however, that a value should never be used that results in a “bytes per cluster” value (BPB_BytsPerSec * BPB_SecPerClus) greater than 32K (32 * 1024). There is a misconception that values greater than this are OK. Values that cause a cluster size greater than 32K bytes do not work properly; do not try to define one. Some versions of some systems allow 64K bytes per cluster value. Many application setup programs will not work correctly on such a FAT volume.
BPB_RsvdSecCnt
14
2
Number of reserved sectors in the Reserved region of the volume starting at the first sector of the volume. This field must not be 0. For FAT12 and FAT16 volumes, this value should never be anything other than 1. For FAT32 volumes, this value is typically 32. There is a lot of FAT code in the world “hard wired” to 1 reserved sector for FAT12 and FAT16 volumes and that doesn’t bother to check this field to make sure it is 1. Microsoft operating systems will properly support any non-zero value in this field.
BPB_NumFATs
16
1
The count of FAT data structures on the volume. This field should always contain the value 2 for any FAT volume of any type. Although any value greater than or equal to 1 is perfectly valid, many software programs and a few operating systems’ FAT file system drivers may not function properly if the value is something other than 2. All Microsoft file system drivers will support a value other than 2, but it is still highly recommended that no value other than 2 be used in this field.

The reason the standard value for this field is 2 is to provide redun­dancy for the FAT data structure so that if a sector goes bad in one of the FATs, that data is not lost because it is duplicated in the other FAT. On non-disk-based media, such as FLASH memory cards, where such redundancy is a useless feature, a value of 1 may be used to save the space that a second copy of the FAT uses, but some FAT file system drivers might not recognize such a volume properly.
BPB_RootEntCnt
17
2
For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes, this value should always specify a count that when multiplied by 32 results in an even multiple of BPB_BytsPerSec. For maximum compatibility, FAT16 volumes should use the value 512.
BPB_TotSec16
19
2
This field is the old 16-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec32 must be non-zero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes, this field contains the sector count, and BPB_TotSec32 is 0 if the total sector count “fits” (is less than 0x10000).
BPB_Media
21
1
0xF8 is the standard value for “fixed” (non-removable) media. For removable media, 0xF0 is frequently used. The legal values for this field are 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, and 0xFF. The only other important point is that whatever value is put in here must also be put in the low byte of the FAT[0] entry. This dates back to the old MS-DOS 1.x media determination noted earlier and is no longer usually used for anything.
BPB_FATSz16
22
2
This field is the FAT12/FAT16 16-bit count of sectors occupied by ONE FAT. On FAT32 volumes this field must be 0, and BPB_FATSz32 contains the FAT size count.
BPB_SecPerTrk
24
2
Sectors per track for interrupt 0x13. This field is only relevant for media that have a geometry (volume is broken down into tracks by multiple heads and cylinders) and are visible on interrupt 0x13. This field contains the “sectors per track” geometry value.
BPB_NumHeads
26
2
Number of heads for interrupt 0x13. This field is relevant as discussed earlier for BPB_SecPerTrk. This field contains the one based “count of heads”. For example, on a 1.44 MB 3.5-inch floppy drive this value is 2.
BPB_HiddSec
28
4
Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13. This field should always be zero on media that are not partitioned. Exactly what value is appropriate is operating system specific.
BPB_TotSec32
32
4
This field is the new 32-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec16 must be non-zero. For FAT32 volumes, this field must be non-zero. For FAT12/FAT16 volumes, this field contains the sector count if BPB_TotSec16 is 0 (count is greater than or equal to 0x10000).

At this point, the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32. The first table shows the structure for FAT12 and FAT16 starting at offset 36 of the boot sector.

Fat12 and Fat16 Structure Starting at Offset 36
Name
Offset (byte)
Size (bytes)
Description
BS_DrvNum
36
1
Int 0x13 drive number (e.g. 0x80). This field supports MS-DOS bootstrap and is set to the INT 0x13 drive number of the media (0x00 for floppy disks, 0x80 for hard disks). NOTE: This field is actually operating system specific.
BS_Reserved1
37
1
Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
BS_BootSig
38
1
Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
BS_VolID
39
4
Volume serial number. This field, together with BS_VolLab, supports volume tracking on removable media. These values allow FAT file system drivers to detect that the wrong disk is inserted in a removable drive. This ID is usually generated by simply combining the current date and time into a 32-bit value.
BS_VolLab
43
11
Volume label. This field matches the 11-byte volume label recorded in the root directory. NOTE: FAT file system drivers should make sure that they update this field when the volume label file in the root directory has its name changed or created. The setting for this field when there is no volume label is the string “NO NAME ”.
BS_FilSysType
54
8
One of the strings “FAT12 ”, “FAT16 ”, or “FAT ”. NOTE: Many people think that the string in this field has something to do with the determination of what type of FAT—FAT12, FAT16, or FAT32—that the volume has. This is not true. You will note from its name that this field is not actually part of the BPB. This string is informational only and is not used by Microsoft file system drivers to determine FAT typ,e because it is frequently not set correctly or is not present. See the FAT Type Determination section of this document. This string should be set based on the FAT type though, because some non-Microsoft FAT file system drivers do look at it.

Here is the structure for FAT32 starting at offset 36 of the boot sector.

FAT32 Structure Starting at Offset 36
Name
Offset (byte)
Size (bytes)
Description
BPB_FATSz32
36
4
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0.
BPB_ExtFlags
40
2
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media.
Bits 0-3 -- Zero-based number of active FAT. Only valid if mirroring is disabled.
Bits 4-6 -- Reserved.
Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
-- 1 means only one FAT is active; it is the one referenced in bits 0-3.
Bits 8-15 -- Reserved.
BPB_FSVer
42
2
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. High byte is major revision number. Low byte is minor revision number. This is the version number of the FAT32 volume. This supports the ability to extend the FAT32 media type in the future without worrying about old FAT32 drivers mounting the volume. This document defines the version to 0:0. If this field is non-zero, back-level Windows versions will not mount the volume.
NOTE: Disk utilities should respect this field and not operate on volumes with a higher major or minor version number than that for which they were designed. FAT32 file system drivers must check this field and not mount the volume if it does not contain a version number that was defined at the time the driver was written.
BPB_RootClus
44
4
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. This is set to the cluster number of the first cluster of the root directory, usually 2 but not required to be 2.
NOTE: Disk utilities that change the location of the root directory should make every effort to place the first cluster of the root directory in the first non-bad cluster on the drive (i.e., in cluster 2, unless it’s marked bad). This is specified so that disk repair utilities can easily find the root directory if this field accidentally gets zeroed.
BPB_FSInfo
48
2
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
NOTE: There will be a copy of the FSINFO structure in BackupBoot, but only the copy pointed to by this field will be kept up to date (i.e., both the primary and backup boot record will point to the same FSINFO sector).
BPB_BkBootSec
50
2
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. No value other than 6 is recommended.
BPB_Reserved
52
12
This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Reserved for future expansion. Code that formats FAT32 volumes should always set all of the bytes of this field to 0.
BS_DrvNum
64
1
This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.
BS_Reserved1
65
1
This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.
BS_BootSig
66
1
This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.
BS_VolID
67
4
This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.
BS_VolLab
71
11
This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.
BS_FilSysType
82
8
Always set to the string ”FAT32 ”. Please see the note for this field in the FAT12/FAT16 section earlier. This field has nothing to do with FAT type determination.

There is one other important note about Sector 0 of a FAT volume. If we consider the contents of the sector as a byte array, it must be true that sector[510] equals 0x55, and sector[511] equals 0xAA.

NOTE: Many FAT documents mistakenly say that this 0xAA55 signature occupies the “last 2 bytes of the boot sector”. This statement is correct if — and only if — BPB_BytsPerSec is 512. If BPB_BytsPerSec is greater than 512, the offsets of these signature bytes do not change (although it is perfectly OK for the last two bytes at the end of the boot sector to also contain this signature).

Check your assumptions about the value in the BPB_TotSec16/32 field. Assume we have a disk or partition of size in sectors DskSz. If the BPB TotSec field (either BPB_TotSec16 or BPB_TotSec32 — whichever is non-zero) is less than or equal to DskSz, there is nothing whatsoever wrong with the FAT volume. In fact, it is not at all unusual to have a BPB_TotSec16/32 value that is slightly smaller than DskSz. It is also perfectly OK for the BPB_TotSec16/32 value to be considerably smaller than DskSz.

All this means is that disk space is being wasted. It does not by itself mean that the FAT volume is damaged in some way. However, if BPB_TotSec16/32 is larger than DskSz, the volume is seriously damaged or malformed because it extends past the end of the media or overlaps data that follows it on the disk. Treating a volume for which the BPB_TotSec16/32 value is “too large” for the media or partition as valid can lead to catastrophic data loss.

FAT Data Structure
The next data structure that is important is the FAT itself. What this data structure does is define a singly linked list of the “extents” (clusters) of a file. Note at this point that a FAT directory or file container is nothing but a regular file that has a special attribute indicating it is a directory. The only other special thing about a directory is that the data or contents of the “file” is a series of 32=byte FAT directory entries (see discussion below). In all other respects, a directory is just like a file. The FAT maps the data region of the volume by cluster number. The first data cluster is cluster 2.

The first sector of cluster 2 (the data region of the disk) is computed using the BPB fields for the volume as follows. First, we determine the count of sectors occupied by the root directory:

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;

Note that on a FAT32 volume the BPB_RootEntCnt value is always 0, so on a FAT32 volume RootDirSectors is always 0. The 32 in the above is the size of one FAT directory entry in bytes. Note also that this computation rounds up.

The start of the data region, the first sector of cluster 2, is computed as follows:

If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;

FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;

NOTE: This sector number is relative to the first sector of the volume that contains the BPB (the sector that contains the BPB is sector number 0). This does not necessarily map directly onto the drive, because sector 0 of the volume is not necessarily sector 0 of the drive due to partitioning.

Given any valid data cluster number N, the sector number of the first sector of that cluster (again relative to sector 0 of the FAT volume) is computed as follows:

FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;

NOTE: Because BPB_SecPerClus is restricted to powers of 2 (1,2,4,8,16,32….), this means that division and multiplication by BPB_SecPerClus can actually be performed via SHIFT operations on 2s complement architectures that are usually faster instructions than MULT and DIV instructions. On current Intel X86 processors, this is largely irrelevant though because the MULT and DIV machine instructions are heavily optimized for multiplication and division by powers of 2.

FAT Type Determination
There is considerable confusion over exactly how this works, which leads to many “off by 1”, “off by 2”, “off by 10”, and “massively off” errors. It is really quite simple how this works. The FAT type—one of FAT12, FAT16, or FAT32—is determined by the count of clusters on the volume and nothing else.

Please read everything in this section carefully, all of the words are important. For example, note that the statement was “count of clusters.” This is not the same thing as “maximum valid cluster number,” because the first data cluster is 2 and not 0 or 1.

To begin, let’s discuss exactly how the “count of clusters” value is determined. This is all done using the BPB fields for the volume. First, we determine the count of sectors occupied by the root directory as noted earlier.

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;

Note that on a FAT32 volume, the BPB_RootEntCnt value is always 0; so on a FAT32 volume, RootDirSectors is always 0.

Next, we determine the count of sectors in the data region of the volume:

If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;

If(BPB_TotSec16 != 0)
TotSec = BPB_TotSec16;
Else
TotSec = BPB_TotSec32;

DataSec = TotSec – (BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors);

Now we determine the count of clusters:

CountofClusters = DataSec / BPB_SecPerClus;

Please note that this computation rounds down.

Now we can determine the FAT type. Please note carefully or you will commit an off-by-one error!

In the following example, when it says <, it does not mean <=. Note also that the numbers are correct. The first number for FAT12 is 4085; the second number for FAT16 is 65525. These numbers and the ‘<’ signs are not wrong.

If(CountofClusters < 4085) {
/* Volume is FAT12 */
} else if(CountofClusters < 65525) {
/* Volume is FAT16 */
} else {
/* Volume is FAT32 */
}

This is the one and only way that FAT type is determined. There is no such thing as a FAT12 volume that has more than 4084 clusters. There is no such thing as a FAT16 volume that has less than 4085 clusters or more than 65,524 clusters. There is no such thing as a FAT32 volume that has less than 65,525 clusters. If you try to make a FAT volume that violates this rule, Microsoft operating systems will not handle them correctly because they will think the volume has a different type of FAT than what you think it does.

NOTE: As is noted numerous times earlier, the world is full of FAT code that is wrong. There is a lot of FAT type code that is off by 1 or 2 or 8 or 10 or 16. For this reason, it is highly recommended that if you are formatting a FAT volume which has maximum compatibility with all existing FAT code, then you should you avoid making volumes of any type that have close to 4,085 or 65,525 clusters. Stay at least 16 clusters on each side away from these cut-over cluster counts.

Note also that the CountofClusters value is exactly that—the count of data clusters starting at cluster 2. The maximum valid cluster number for the volume is CountofClusters + 1, and the “count of clusters including the two reserved clusters” is CountofClusters + 2.

There is one more important computation related to the FAT. Given any valid cluster number N, where in the FAT(s) is the entry for that cluster number? The only FAT type for which this is complex is FAT12. For FAT16 and FAT32, the computation is simple:

If(BPB_FATSz16 != 0)
FATSz = BPB_FATSz16;
Else
FATSz = BPB_FATSz32;

If(FATType == FAT16)
FATOffset = N * 2;
Else if (FATType == FAT32)
FATOffset = N * 4;

ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

REM(…) is the remainder operator. That means the remainder after division of FATOffset by BPB_BytsPerSec. ThisFATSecNum is the sector number of the FAT sector that contains the entry for cluster N in the first FAT. If you want the sector number in the second FAT, you add FATSz to ThisFATSecNum; for the third FAT, you add 2*FATSz, and so on.

You now read sector number ThisFATSecNum (remember this is a sector number relative to sector 0 of the FAT volume). Assume this is read into an 8-bit byte array named SecBuff. Also assume that the type WORD is a 16-bit unsigned and that the type DWORD is a 32-bit unsigned.

If(FATType == FAT16)
FAT16ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);
Else
FAT32ClusEntryVal = (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0x0FFFFFFF;

Fetches the contents of that cluster. To set the contents of this same cluster you do the following:

If(FATType == FAT16)
*((WORD *) &SecBuff[ThisFATEntOffset]) = FAT16ClusEntryVal;
Else {
FAT32ClusEntryVal = FAT32ClusEntryVal & 0x0FFFFFFF;
*((DWORD *) &SecBuff[ThisFATEntOffset]) =
(*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0xF0000000;
*((DWORD *) &SecBuff[ThisFATEntOffset]) =
(*((DWORD *) &SecBuff[ThisFATEntOffset])) FAT32ClusEntryVal;
}

Note how the FAT32 code above works. A FAT32 FAT entry is actually only a 28-bit entry. The high 4 bits of a FAT32 FAT entry are reserved. The only time that the high 4 bits of FAT32 FAT entries should ever be changed is when the volume is formatted, at which time the whole 32-bit FAT entry should be zeroed, including the high 4 bits.

A bit more explanation is in order here, because this point about FAT32 FAT entries seems to cause a great deal of confusion. Basically 32-bit FAT entries are not really 32-bit values; they are only 28-bit values. For example, all of these 32-bit cluster entry values: 0x10000000, 0xF0000000, and 0x00000000 all indicate that the cluster is FREE, because you ignore the high 4 bits when you read the cluster entry value. If the 32-bit free cluster value is currently 0x30000000 and you want to mark this cluster as bad by storing the value 0x0FFFFFF7 in it. Then the 32-bit entry will contain the value 0x3FFFFFF7 when you are done, because you must preserve the high 4 bits when you write in the 0x0FFFFFF7 bad cluster mark.

Take note that because the BPB_BytsPerSec value is always divisible by 2 and 4, you never have to worry about a FAT16 or FAT32 FAT entry spanning over a sector boundary (this is not true of FAT12).

The code for FAT12 is more complicated because there are 1.5 bytes (12-bits) per FAT entry.

if (FATType == FAT12)
FATOffset = N + (N / 2);
/* Multiply by 1.5 without using floating point, the divide by 2 rounds DOWN */

ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
ThisFATEntOffset = REM(FATOffset / BPB_BytsPerSec);

We now have to check for the sector boundary case:

If(ThisFATEntOffset == (BPB_BytsPerSec – 1)) {
/* This cluster access spans a sector boundary in the FAT */
/* There are a number of strategies to handling this. The */
/* easiest is to always load FAT sectors into memory */
/* in pairs if the volume is FAT12 (if you want to load */
/* FAT sector N, you also load FAT sector N+1 immediately */
/* following it in memory unless sector N is the last FAT */
/* sector). It is assumed that this is the strategy used here */
/* which makes this if test for a sector boundary span */
/* unnecessary. */
}

We now access the FAT entry as a WORD just as we do for FAT16, but if the cluster number is EVEN, we only want the low 12-bits of the 16-bits we fetch; and if the cluster number is ODD, we only want the high 12-bits of the 16-bits we fetch.

FAT12ClusEntryVal = *((WORD *) &SecBuff[ThisFATEntOffset]);
If(N & 0x0001)
FAT12ClusEntryVal = FAT12ClusEntryVal >> 4; /* Cluster number is ODD */
Else
FAT12ClusEntryVal = FAT12ClusEntryVal & 0x0FFF; /* Cluster number is EVEN */

Fetches the contents of that cluster. To set the contents of this same cluster you do the following:

If(N & 0x0001) {
FAT12ClusEntryVal = FAT12ClusEntryVal << 4; /* Cluster number is ODD */
*((WORD *) &SecBuff[ThisFATEntOffset]) =
(*((WORD *) &SecBuff[ThisFATEntOffset])) & 0x000F;
} Else {
FAT12ClusEntryVal = FAT12ClusEntryVal & 0x0FFF; /* Cluster number is EVEN */
*((WORD *) &SecBuff[ThisFATEntOffset]) =
(*((WORD *) &SecBuff[ThisFATEntOffset])) & 0xF000;
}
*((WORD *) &SecBuff[ThisFATEntOffset]) =
(*((WORD *) &SecBuff[ThisFATEntOffset])) FAT12ClusEntryVal;

NOTE: It is assumed that the >> operator shifts a bit value of 0 into the high 4 bits and that the << operator shifts a bit value of 0 into the low 4 bits.

The way the data of a file is associated with the file is as follows. In the directory entry, the cluster number of the first cluster of the file is recorded. The first cluster (extent) of the file is the data associated with this first cluster number, and the location of that data on the volume is computed from the cluster number as described earlier (computation of FirstSectorofCluster).

Note that a zero-length file—a file that has no data allocated to it—has a first cluster number of 0 placed in its directory entry. This cluster location in the FAT (see earlier computation of ThisFATSecNum and ThisFATEntOffset) contains either an EOC mark (End Of Clusterchain) or the cluster number of the next cluster of the file. The EOC value is FAT type dependant (assume FATContent is the contents of the cluster entry in the FAT being checked to see whether it is an EOC mark):

IsEOF = FALSE;
If(FATType == FAT12) {
If(FATContent >= 0x0FF8)
IsEOF = TRUE;
} else if(FATType == FAT16) {
If(FATContent >= 0xFFF8)
IsEOF = TRUE;
} else if (FATType == FAT32) {
If(FATContent >= 0x0FFFFFF8)
IsEOF = TRUE;
}

Note that the cluster number whose cluster entry in the FAT contains the EOC mark is allocated to the file and is also the last cluster allocated to the file. Microsoft operating system FAT drivers use the EOC value 0x0FFF for FAT12, 0xFFFF for FAT16, and 0x0FFFFFFF for FAT32 when they set the contents of a cluster to the EOC mark. There are various disk utilities for Microsoft operating systems that use a different value, however.

There is also a special “BAD CLUSTER” mark. Any cluster that contains the “BAD CLUSTER” value in its FAT entry is a cluster that should not be placed on the free list because it is prone to disk errors. The “BAD CLUSTER” value is 0x0FF7 for FAT12, 0xFFF7 for FAT16, and 0x0FFFFFF7 for FAT32. The other relevant note here is that these bad clusters are also lost clusters—clusters that appear to be allocated because they contain a non-zero value but which are not part of any files allocation chain. Disk repair utilities must recognize lost clusters that contain this special value as bad clusters and not change the content of the cluster entry.

NOTE: It is not possible for the bad cluster mark to be an allocatable cluster number on FAT12 and FAT16 volumes, but it is feasible for 0x0FFFFFF7 to be an allocatable cluster number on FAT32 volumes. To avoid possible confusion by disk utilities, no FAT32 volume should ever be configured such that 0x0FFFFFF7 is an allocatable cluster number.

The list of free clusters in the FAT is nothing more than the list of all clusters that contain the value 0 in their FAT cluster entry. Note that this value must be fetched as described earlier as for any other FAT entry that is not free. This list of free clusters is not stored anywhere on the volume; it must be computed when the volume is mounted by scanning the FAT for entries that contain the value 0. On FAT32 volumes, the BPB_FSInfo sector may contain a valid count of free clusters on the volume. See the documentation of the FAT32 FSInfo sector.

What are the two reserved clusters at the start of the FAT for? The first reserved cluster, FAT[0], contains the BPB_Media byte value in its low 8 bits, and all other bits are set to 1. For example, if the BPB_Media value is 0xF8, for FAT12 FAT[0] = 0x0FF8, for FAT16 FAT[0] = 0xFFF8, and for FAT32 FAT[0] = 0x0FFFFFF8. The second reserved cluster, FAT[1], is set by FORMAT to the EOC mark. On FAT12 volumes, it is not used and is simply always contains an EOC mark. For FAT16 and FAT32, the file system driver may use the high two bits of the FAT[1] entry for dirty volume flags (all other bits, are always left set to 1). Note that the bit location is different for FAT16 and FAT32, because they are the high 2 bits of the entry.

For FAT16:
ClnShutBitMask = 0x8000;
HrdErrBitMask = 0x4000;

For FAT32:
ClnShutBitMask = 0x08000000;
HrdErrBitMask = 0x04000000;

Bit ClnShutBitMask – If bit is 1, volume is “clean”.If bit is 0, volume is “dirty”. This indicates that the file system driver did not Dismount the volume properly the last time it had the volume mounted. It would be a good idea to run a Chkdsk/Scandisk disk repair utility on it, because it may be damaged.
Bit HrdErrBitMask – If this bit is 1, no disk read/write errors were encountered.If this bit is 0, the file system driver encountered a disk I/O error on the Volume the last time it was mounted, which is an indicator that some sectors may have gone bad on the volume. It would be a good idea to run a Chkdsk/Scandisk disk repair utility that does surface analysis on it to look for new bad sectors.

Here are two more important notes about the FAT region of a FAT volume:
1. The last sector of the FAT is not necessarily all part of the FAT. The FAT stops at the cluster number in the last FAT sector that corresponds to the entry for cluster number CountofClusters + 1 (see the CountofClusters computation earlier), and this entry is not necessarily at the end of the last FAT sector. FAT code should not make any assumptions about what the contents of the last FAT sector are after the CountofClusters + 1 entry. FAT format code should zero the bytes after this entry though.
2. The BPB_FATSz16 (BPB_FATSz32 for FAT32 volumes) value may be bigger than it needs to be. In other words, there may be totally unused FAT sectors at the end of each FAT in the FAT region of the volume. For this reason, the last sector of the FAT is always computed using the CountofClusters + 1 value, never from the BPB_FATSz16/32 value. FAT code should not make any assumptions about what the contents of these “extra” FAT sectors are. FAT format code should zero the contents of these extra FAT sectors though.

FAT Volume Initialization
At this point, the careful reader should have one very interesting question. Given that the FAT type (FAT12, FAT16, or FAT32) is dependant on the number of clusters—and that the sectors available in the data area of a FAT volume is dependant on the size of the FAT—when handed an unformatted volume that does not yet have a BPB, how do you determine all this and compute the proper values to put in BPB_SecPerClus and either BPB_FATSz16 or BPB_FATSz32? The way Microsoft operating systems do this is with a fixed value, several tables, and a clever piece of arithmetic.

Microsoft operating systems only do FAT12 on floppy disks. Because there is a limited number of floppy formats that all have a fixed size, this is done with a simple table:

“If it is a floppy of this type, then the BPB looks like this.”

There is no dynamic computation for FAT12. For the FAT12 formats, all the computation for BPB_SecPerClus and BPB_FATSz16 was worked out by hand on a piece of paper and recorded in the table (being careful of course that the resultant cluster count was always less than 4085). If your media is larger than 4 MB, do not bother with FAT12. Use smaller BPB_SecPerClus values so that the volume will be FAT16.

The rest of this section is totally specific to drives that have 512 bytes per sector. You cannot use these tables, or the clever arithmetic, with drives that have a different sector size. The “fixed value” is simply a volume size that is the “FAT16 to FAT32 cutover value”. Any volume size smaller than this is FAT16 and any volume of this size or larger is FAT32. For Windows, this value is 512 MB. Any FAT volume smaller than 512 MB is FAT16, and any FAT volume of 512 MB or larger is FAT32.

Please don’t draw an incorrect conclusion here.

There are many FAT16 volumes out there that are larger than 512 MB. There are various ways to force the format to be FAT16 rather than the default of FAT32, and there is a great deal of code that implements different limits. All we are talking about here is the default cutover value for MS-DOS and Windows on volumes that have not yet been formatted. There are two tables—one is for FAT16 and the other is for FAT32. An entry in these tables is selected based on the size of the volume in 512 byte sectors (the value that will go in BPB_TotSec16 or BPB_TotSec32), and the value that this table sets is the BPB_SecPerClus value.

struct DSKSZTOSECPERCLUS {
DWORD DiskSize;
BYTE SecPerClusVal;
};

/*
*This is the table for FAT16 drives. NOTE that this table includes
* entries for disk sizes larger than 512 MB even though typically
* only the entries for disks < 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 1, BPB_NumFATs
* must be 2, and BPB_RootEntCnt must be 512. Any of these values
* being different may require the first table entries DiskSize value
* to be changed otherwise the cluster count may be to low for FAT16.
*/
DSKSZTOSECPERCLUS DskTableFAT16 [] = {
{ 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */
{ 32680, 2}, /* disks up to 16 MB, 1k cluster */
{ 262144, 4}, /* disks up to 128 MB, 2k cluster */
{ 524288, 8}, /* disks up to 256 MB, 4k cluster */
{ 1048576, 16}, /* disks up to 512 MB, 8k cluster */
/* The entries after this point are not used unless FAT16 is forced */
{ 2097152, 32}, /* disks up to 1 GB, 16k cluster */
{ 4194304, 64}, /* disks up to 2 GB, 32k cluster */
{ 0xFFFFFFFF, 0} /* any disk greater than 2GB, 0 value for SecPerClusVal trips an error */
};

/*
* This is the table for FAT32 drives. NOTE that this table includes
* entries for disk sizes smaller than 512 MB even though typically
* only the entries for disks >= 512 MB in size are used.
* The way this table is accessed is to look for the first entry
* in the table for which the disk size is less than or equal
* to the DiskSize field in that table entry. For this table to
* work properly BPB_RsvdSecCnt must be 32, and BPB_NumFATs
* must be 2. Any of these values being different may require the first
* table entries DiskSize value to be changed otherwise the cluster count
* may be to low for FAT32.
*/
DSKSZTOSECPERCLUS DskTableFAT32 [] = {
{ 66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */
{ 532480, 1}, /* disks up to 260 MB, .5k cluster */
{ 16777216, 8}, /* disks up to 8 GB, 4k cluster */
{ 33554432, 16}, /* disks up to 16 GB, 8k cluster */
{ 67108864, 32}, /* disks up to 32 GB, 16k cluster */
{ 0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */
};

So given a disk size and a FAT type of FAT16 or FAT32, we now have a BPB_SecPerClus value. The only thing we have left is do is to compute how many sectors the FAT takes up so that we can set BPB_FATSz16 or BPB_FATSz32. Note that at this point we assume that BPB_RootEntCnt, BPB_RsvdSecCnt, and BPB_NumFATs are appropriately set. We also assume that DskSize is the size of the volume that we are either going to put in BPB_TotSec32 or BPB_TotSec16.

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;
TmpVal1 = DskSize – (BPB_ResvdSecCnt + RootDirSectors);
TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs;
If(FATType == FAT32)
TmpVal2 = TmpVal2 / 2;
FATSz = (TMPVal1 + (TmpVal2 – 1)) / TmpVal2;
If(FATType == FAT32) {
BPB_FATSz16 = 0;
BPB_FATSz32 = FATSz;
} else {
BPB_FATSz16 = LOWORD(FATSz);
/* there is no BPB_FATSz32 in a FAT16 BPB */
}

Do not spend too much time trying to figure out why this math works. The basis for the computation is complicated; the important point is that this is how Microsoft operating systems do it, and it works. Note, however, that this math does not work perfectly. It will occasionally set a FATSz that is up to 2 sectors too large for FAT16, and occasionally up to 8 sectors too large for FAT32. It will never compute a FATSz value that is too small, however. Because it is OK to have a FATSz that is too large, at the expense of wasting a few sectors, the fact that this computation is surprisingly simple more than makes up for it being off in a safe way in some cases.

FAT32 FSInfo Sector Structure and Backup Boot Sector
On a FAT32 volume, the FAT can be a large data structure, unlike on FAT16 where it is limited to a maximum of 128K worth of sectors and FAT12 where it is limited to a maximum of 6K worth of sectors. For this reason, a provision is made to store the “last known” free cluster count on the FAT32 volume so that it does not have to be computed as soon as an API call is made to ask how much free space there is on the volume (like at the end of a directory listing). The FSInfo sector number is the value in the BPB_FSInfo field; for Microsoft operating systems it is always set to 1. Here is the structure of the FSInfo sector:

FAT32 FSInfo Sector Structure and Backup Boot Sector
Name
Offset (byte)
Size (bytes)
Description
FSI_LeadSig
0
4
Value 0x41615252. This lead signature is used to validate that this is in fact an FSInfo sector.
FSI_Reserved1
4
480
This field is currently reserved for future expansion. FAT32 format code should always initialize all bytes of this field to 0. Bytes in this field must currently never be used.
FSI_StrucSig
484
4
Value 0x61417272. Another signature that is more localized in the sector to the location of the fields that are used.
FSI_Free_Count
488
4
Contains the last known free cluster count on the volume. If the value is 0xFFFFFFFF, then the free count is unknown and must be computed. Any other value can be used, but is not necessarily correct. It should be range checked at least to make sure it is <= volume cluster count.
FSI_Nxt_Free
492
4
This is a hint for the FAT driver. It indicates the cluster number at which the driver should start looking for free clusters. Because a FAT32 FAT is large, it can be rather time consuming if there are a lot of allocated clusters at the start of the FAT and the driver starts looking for a free cluster starting at cluster 2. Typically this value is set to the last cluster number that the driver allocated. If the value is 0xFFFFFFFF, then there is no hint and the driver should start looking at cluster 2. Any other value can be used, but should be checked first to make sure it is a valid cluster number for the volume.
FSI_Reserved2
496
12
This field is currently reserved for future expansion. FAT32 format code should always initialize all bytes of this field to 0. Bytes in this field must currently never be used.
FSI_TrailSig
508
4
Value 0xAA550000. This trail signature is used to validate that this is in fact an FSInfo sector. Note that the high 2 bytes of this value—which go into the bytes at offsets 510 and 511—match the signature bytes used at the same offsets in sector 0.

Another feature on FAT32 volumes that is not present on FAT16/FAT12 is the BPB_BkBootSec field. FAT16/FAT12 volumes can be totally lost if the contents of sector 0 of the volume are overwritten or sector 0 goes bad and cannot be read. This is a “single point of failure” for FAT16 and FAT12 volumes. The BPB_BkBootSec field reduces the severity of this problem for FAT32 volumes, because starting at that sector number on the volume—6—there is a backup copy of the boot sector information including the volume’s BPB.

In the case where the sector 0 information has been accidentally overwritten, all a disk repair utility has to do is restore the boot sector(s) from the backup copy. In the case where sector 0 goes bad, this allows the volume to be mounted so that the user can access data before replacing the disk.

This second case—sector 0 goes bad—is the reason why no value other than 6 should ever be placed in the BPB_BkBootSec field. If sector 0 is unreadable, various operating systems are “hard wired” to check for backup boot sector(s) starting at sector 6 of the FAT32 volume. Note that starting at the BPB_BkBootSec sector is a complete boot record. The Microsoft FAT32 “boot sector” is actually three 512-byte sectors long. There is a copy of all three of these sectors starting at the BPB_BkBootSec sector. A copy of the FSInfo sector is also there, even though the BPB_FSInfo field in this backup boot sector is set to the same value as is stored in the sector 0 BPB.

NOTE: All 3 of these sectors have the 0xAA55 signature in sector offsets 510 and 511, just like the first boot sector does (see the earlier discussion at the end of the BPB structure description).

FAT Directory Structure
We will first talk about short directory entries and ignore long directory entries for the moment.

A FAT directory is nothing but a “file” composed of a linear list of 32-byte structures. The only special directory, which must always be present, is the root directory. For FAT12 and FAT16 media, the root directory is located in a fixed location on the disk immediately following the last FAT and is of a fixed size in sectors computed from the BPB_RootEntCnt value (see computations for RootDirSectors earlier in this document). For FAT12 and FAT16 media, the first sector of the root directory is sector number relative to the first sector of the FAT volume:

FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16);

For FAT32, the root directory can be of variable size and is a cluster chain, just like any other directory is. The first cluster of the root directory on a FAT32 volume is stored in BPB_RootClus. Unlike other directories, the root directory itself on any FAT type does not have any date or time stamps, does not have a file name (other than the implied file name “\”), and does not contain “.” and “..” files as the first two directory entries in the directory. The only other special aspect of the root directory is that it is the only directory on the FAT volume for which it is valid to have a file that has only the ATTR_VOLUME_ID attribute bit set (see below).

FAT 32 Byte Directory Entry Structure
Name
Offset (byte)
Size (bytes)
Description
DIR_Name
0
11
Short name.
DIR_Attr
11
1
File attributes:
ATTR_READ_ONLY 0x01
ATTR_HIDDEN 0x02
ATTR_SYSTEM 0x04
ATTR_VOLUME_ID 0x08
ATTR_DIRECTORY 0x10
ATTR_ARCHIVE 0x20
ATTR_LONG_NAME ATTR_READ_ONLY ATTR_HIDDEN ATTR_SYSTEM ATTR_VOLUME_ID
The upper two bits of the attribute byte are reserved and should always be set to 0 when a file is created and never modified or looked at after that.
DIR_NTRes
12
1
Reserved for use by Windows NT. Set value to 0 when a file is created and never modify or look at it after that.
DIR_CrtTimeTenth
13
1
Millisecond stamp at file creation time. This field actually contains a count of tenths of a second. The granularity of the seconds part of DIR_CrtTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive.
DIR_CrtTime
14
2
Time file was created.
DIR_CrtDate
16
2
Date file was created.
DIR_LstAccDate
18
2
Last access date. Note that there is no last access time, only a date. This is the date of last read or write. In the case of a write, this should be set to the same date as DIR_WrtDate.
DIR_FstClusHI
20
2
High word of this entry’s first cluster number (always 0 for a FAT12 or FAT16 volume).
DIR_WrtTime
22
2
Time of last write. Note that file creation is considered a write.
DIR_WrtDate
24
2
Date of last write. Note that file creation is considered a write.
DIR_FstClusLO
26
2
Low word of this entry’s first cluster number.
DIR_FileSize
28
4
32-bit DWORD holding this file’s size in bytes.


DIR_Name[0]
Special notes about the first byte (DIR_Name[0]) of a FAT directory entry:

· If DIR_Name[0] == 0xE5, then the directory entry is free (there is no file or directory name in this entry).

· If DIR_Name[0] == 0x00, then the directory entry is free (same as for 0xE5), and there are no allocated directory entries after this one (all of the DIR_Name[0] bytes in all of the entries after this one are also set to 0).

The special 0 value, rather than the 0xE5 value, indicates to FAT file system driver code that the rest of the entries in this directory do not need to be examined because they are all free.

· If DIR_Name[0] == 0x05, then the actual file name character for this byte is 0xE5. 0xE5 is actually a valid KANJI lead byte value for the character set used in Japan. The special 0x05 value is used so that this special file name case for Japan can be handled properly and not cause FAT file system code to think that the entry is free.

The DIR_Name field is actually broken into two parts+ the 8-character main part of the name, and the 3-character extension. These two parts are “trailing space padded” with bytes of 0x20.

DIR_Name[0] may not equal 0x20. There is an implied ‘.’ character between the main part of the name and the extension part of the name that is not present in DIR_Name. Lower case characters are not allowed in DIR_Name (what these characters are is country specific).

The following characters are not legal in any bytes of DIR_Name:
· Values less than 0x20 except for the special case of 0x05 in DIR_Name[0] described above.
· 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, and 0x7C.

Here are some examples of how a user-entered name maps into DIR_Name:

“foo.bar” -> “FOO BAR”
“FOO.BAR” -> “FOO BAR”
“Foo.Bar” -> “FOO BAR”
“foo” -> “FOO “
“foo.” -> “FOO “
“PICKLE.A” -> “PICKLE A “
“prettybg.big” -> “PRETTYBGBIG”
“.big” -> illegal, DIR_Name[0] cannot be 0x20

In FAT directories all names are unique. Look at the first three examples earlier. Those different names all refer to the same file, and there can only be one file with DIR_Name set to “FOO BAR” in any directory.

DIR_Attr specifies attributes of the file:

ATTR_READ_ONLY Indicates that writes to the file should fail.
ATTR_HIDDEN Indicates that normal directory listings should not show this file.
ATTR_SYSTEM Indicates that this is an operating system file.
ATTR_VOLUME_ID There should only be one “file” on the volume that has this attribute set, and that file must be in the root directory. This name of this file is actually the label for the volume. DIR_FstClusHI and DIR_FstClusLO must always be 0 for the volume label (no data clusters are allocated to the volume label file).
ATTR_DIRECTORY Indicates that this file is actually a container for other files.
ATTR_ARCHIVE This attribute supports backup utilities. This bit is set by the FAT file system driver when a file is created, renamed, or written to. Backup utilities may use this attribute to indicate which files on the volume have been modified since the last time that a backup was performed.

Note that the ATTR_LONG_NAME attribute bit combination indicates that the “file” is actually part of the long name entry for some other file. See the next section for more information on this attribute combination.

When a directory is created, a file with the ATTR_DIRECTORY bit set in its DIR_Attr field, you set its DIR_FileSize to 0. DIR_FileSize is not used and is always 0 on a file with the ATTR_DIRECTORY attribute (directories are sized by simply following their cluster chains to the EOC mark). One cluster is allocated to the directory (unless it is the root directory on a FAT16/FAT12 volume), and you set DIR_FstClusLO and DIR_FstClusHI to that cluster number and place an EOC mark in that clusters entry in the FAT. Next, you initialize all bytes of that cluster to 0. If the directory is the root directory, you are done (there are no dot or dotdot entries in the root directory). If the directory is not the root directory, you need to create two special entries in the first two 32-byte directory entries of the directory (the first two 32 byte entries in the data region of the cluster you just allocated).

The first directory entry has DIR_Name set to:
“. ”

The second has DIR_Name set to:
“.. ”

These are called the dot and dotdot entries. The DIR_FileSize field on both entries is set to 0, and all of the date and time fields in both of these entries are set to the same values as they were in the directory entry for the directory that you just created. You now set DIR_FstClusLO and DIR_FstClusHI for the dot entry (the first entry) to the same values you put in those fields for the directories directory entry (the cluster number of the cluster that contains the dot and dotdot entries).

Finally, you set DIR_FstClusLO and DIR_FstClusHI for the dotdot entry (the second entry) to the first cluster number of the directory in which you just created the directory (value is 0 if this directory is the root directory even for FAT32 volumes).

Here is the summary for the dot and dotdot entries:
· The dot entry is a directory that points to itself.
· The dotdot entry points to the starting cluster of the parent of this directory (which is 0 if this directories parent is the root directory).

Date and Time Formats
Many FAT file systems do not support Date/Time other than DIR_WrtTime and DIR_WrtDate. For this reason, DIR_CrtTimeMil, DIR_CrtTime, DIR_CrtDate, and DIR_LstAccDate are actually optional fields. DIR_WrtTime and DIR_WrtDate must be supported, however. If the other date and time fields are not supported, they should be set to 0 on file create and ignored on other file operations.

Date Format. A FAT directory entry date stamp is a 16-bit field that is basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word):

Bits 0–4: Day of month, valid value range 1-31 inclusive.
Bits 5–8: Month of year, 1 = January, valid value range 1–12 inclusive.
Bits 9–15: Count of years from 1980, valid value range 0–127 inclusive (1980–2107).

Time Format. A FAT directory entry time stamp is a 16-bit field that has a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word).

Bits 0–4: 2-second count, valid value range 0–29 inclusive (0 – 58 seconds).
Bits 5–10: Minutes, valid value range 0–59 inclusive.
Bits 11–15: Hours, valid value range 0–23 inclusive.

The valid time range is from Midnight 00:00:00 to 23:59:58.

FAT Long Directory Entries
In adding long directory entries to the FAT file system it was crucial that their addition to the FAT file system's existing design:

Be essentially transparent on earlier versions of MS-DOS. The primary goal being that existing MS-DOS APIs on previous versions of MS-DOS/Windows do not easily "find" long directory entries. The only MS-DOS APIs that can "find" long directory entries are the FCB-based-find APIs when used with a full meta-character matching pattern (i.e. *.*) and full attribute matching bits (i.e. matching attributes are FFh). On post-Windows 95 versions of MS-DOS/Windows, no MS-DOS API can accidentally "find" a single long directory entry.
Be located in close physical proximity, on the media, to the short directory entries they are associated with. As will be evident, long directory entries are immediately contiguous to the short directory entry they are associated with and their existence imposes an unnoticeable performance impact on the file system.
If detected by disk maintenance utilities, they do not jeopardize the integrity of existing file data. Disk maintenance utilities typically do not use MS-DOS APIs to access on-media file-system-specific data structures. Rather they read physical or logical sector information from the disk and judge for themselves what the directory entries contain. Based on the heuristics employed in the utilities, the utility may take various steps to "repair" what it perceives to be "damaged" file-system-specific data structures. Long directory entries were added to the FAT file system in such a way as to not cause the loss of file data if a disk containing long directory entries was "repaired" by a pre-Windows 95-compatible disk utility on a previous version of MS-DOS/Windows.

In order to meet the goals of locality-of-access and transparency, the long directory entry is defined as a short directory entry with a special attribute. As described previously, a long directory entry is just a regular directory entry in which the attribute field has a value of:

ATTR_LONG_NAME ATTR_READ_ONLY ATTR_HIDDEN ATTR_SYSTEM ATTR_VOLUME_ID

A mask for determining whether an entry is a long-name sub-component should also be defined:

ATTR_LONG_NAME_MASK ATTR_READ_ONLY ATTR_HIDDEN ATTR_SYSTEM ATTR_VOLUME_ID ATTR_DIRECTORY ATTR_ARCHIVE
When such a directory entry is encountered it is given special treatment by the file system. It is treated as part of a set of directory entries that are associated with a single short directory entry. Each long directory entry has the following structure:

FAT Long Directory Entry Structure
Name
Offset
(byte)
Size
(bytes)
Description
LDIR_Ord
0
1
The order of this entry in the sequence of long dir entries associated with the short dir entry at the end of the long dir set.
If masked with 0x40 (LAST_LONG_ENTRY), this indicates the entry is the last long dir entry in a set of long dir entries. All valid sets of long dir entries must begin with an entry having this mask.
LDIR_Name1
1
10
Characters 1-5 of the long-name sub-component in this dir entry.
LDIR_Attr
11
1
Attributes - must be ATTR_LONG_NAME
LDIR_Type
12
1
If zero, indicates a directory entry that is a sub-component of a long name. NOTE: Other values reserved for future extensions.
Non-zero implies other dirent types.
LDIR_Chksum
13
1
Checksum of name in the short dir entry at the end of the long dir set.
LDIR_Name2
14
12
Characters 6-11 of the long-name sub-component in this dir entry.
LDIR_FstClusLO
26
2
Must be ZERO. This is an artifact of the FAT "first cluster" and must be zero for compatibility with existing disk utilities. It's meaningless in the context of a long dir entry.
LDIR_Name3
28
4
Characters 12-13 of the long-name sub-component in this dir entry.

Organization and Association of Short & Long Directory Entries

A set of long entries is always associated with a short entry that they always immediately precede. Long entries are paired with short entries for one reason: only short directory entries are visible to previous versions of MS-DOS/Windows. Without a short entry to accompany it, a long directory entry would be completely invisible on previous versions of MS-DOS/Windows. A long entry never legally exists all by itself. If long entries are found without being paired with a valid short entry, they are termed orphans. The following figure depicts a set of n long directory entries associated with it's single short entry.

Long entries always immediately precede and are physically contiguous with, the short entry they are associated with. The file system makes a few other checks to ensure that a set of long entries is actually associated with a short entry.

Sequence Of Long Directory Entries
Entry
Ordinal
Nth Long entry
LAST_LONG_ENTRY (0x40) N
… Additional Long Entries

1st Long entry
1
Short Entry Associated With Preceding Long Entries
(not applicable)

First, every member of a set of long entries is uniquely numbered and the last member of the set is or'd with a flag indicating that it is, in fact, the last member of the set. The LDIR_Ord field is used to make this determination. The first member of a set has an LDIR_Ord value of one. The nth long member of the set has a value of (n OR LAST_LONG_ENTRY). Note that the LDIR_Ord field cannot have values of 0xE5 or 0x00. These values have always been used by the file system to indicate a "free" directory entry, or the "last" directory entry in a cluster. Values for LDIR_Ord do not take on these two values over their range. Values for LDIR_Ord must run from 1 to (n OR LAST_LONG_ENTRY). If they do not, the long entries are "damaged" and are treated as orphans by the file system.

Second, an 8-bit checksum is computed on the name contained in the short directory entry at the time the short and long directory entries are created. All 11 characters of the name in the short entry are used in the checksum calculation. The check sum is placed in every long entry. If any of the check sums in the set of long entries do not agree with the computed checksum of the name contained in the short entry, then the long entries are treated as orphans. This can occur if a disk containing long and short entries is taken to a previous version of MS-DOS/Windows and only the short name of a file or directory with a long entries is renamed.

The algorithm, implemented in C, for computing the checksum is:

//----------------------------------------------------------------------------- // ChkSum() // Returns an unsigned byte checksum computed on an unsigned byte // array. The array must be 11 bytes long and is assumed to contain // a name stored in the format of a MS-DOS directory entry. // Passed: pFcbName Pointer to an unsigned byte array assumed to be
// 11 bytes long. // Returns: Sum An 8-bit unsigned checksum of the array pointed
// to by pFcbName. //------------------------------------------------------------------------------ unsigned char ChkSum (unsigned char *pFcbName) { short FcbNameLen; unsigned char Sum; Sum = 0; for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) { // NOTE: The operation is an unsigned char rotate right Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++; } return (Sum); }

As a consequence of this pairing, the short directory entry serves as the structure that contains fields like: last access date, creation time, creation date, first cluster, and size. It also holds a name that is visible on previous versions of MS-DOS/Windows. The long directory entries are free to contain new information and need not replicate information already available in the short entry. Principally, the long entries contain the long name of a file. The name contained in a short entry which is associated with a set of long entries is termed the alias name, or simply alias, of the file.

Storage of a Long-Name Within Long Directory Entries

A long name can consist of more characters than can fit in a single long directory entry. When this occurs the name is stored in more than one long entry. In any event, the name fields themselves within the long entries are disjoint. The following example is provided to illustrate how a long name is stored across several long directory entries. Names are also NUL terminated and padded with 0xFFFF characters in order to detect corruption of long name fields by errant disk utilities. A name that fits exactly in a n long directory entries (i.e. is an integer multiple of 13) is not NUL terminated and not padded with 0xFFFFs.

Suppose a file is created with the name: "The quick brown.fox". The following example illustrates how the name is packed into long and short directory entries. Most fields in the directory entries are also filled in as well.


The heuristics used to "auto-generate" a short name from a long name are explained in a later section.

Name Limits and Character Sets

Short Directory Entries

Short names are limited to 8 characters followed by an optional period (.) and extension of up to 3 characters. The total path length of a short name cannot exceed 80 characters (64 char path + 3 drive letter + 12 for 8.3 name + NUL) including the trailing NUL. The characters may be any combination of letters, digits, or characters with code point values greater than 127. The following special characters are also allowed:

$ % ' - _ @ ~ ` ! ( ) { } ^ # &

Names are stored in a short directory entry in the OEM code page that the system is configured for at the time the directory entry is created. Short directory entries remain in OEM for compatibility with previous versions of MS-DOS/Windows. OEM characters are single 8-bit characters or can be DBCS character pairs for certain code pages.

Short names passed to the file system are always converted to upper case and their original case value is lost. One problem that is generally true of most OEM code pages is that they map lower to upper case extended characters in a non-unique fashion. That is, they map multiple extended characters to a single upper case character. This creates problems because it does not preserve the information that the extended character provides. This mapping also prevents the creation of some file names that would normally differ, but because of the mapping to upper case they become the same file name.

Long Directory Entries

Long names are limited to 255 characters, not including the trailing NUL. The total path length of a long name cannot exceed 260 characters, including the trailing NUL. The characters may be any combination of those defined for short names with the addition of the period (.) character used multiple times within the long name. A space is also a valid character in a long name as it always has been for a short name. However, in short names it typically is not used. The following six special characters are now allowed in a long name. They are not legal in a short name.

+ , ; = [ ]

Embedded spaces within a long name are allowed. Leading and trailing spaces in a long name are ignored.

Leading and embedded periods are allowed in a name and are stored in the long name. Trailing periods are ignored.

Long names are stored in long directory entries in UNICODE. UNICODE characters are 16-bit characters. It is not be possible to store UNICODE in short directory entries since the names stored there are 8-bit characters or DBCS characters.

Long names passed to the file system are not converted to upper case and their original case value is preserved. UNICODE solves the case mapping problem prevalent in some OEM code pages by always providing a translation for lower case characters to a single, unique upper case character.

Name Matching In Short & Long Names
The names contained in the set of all short directory entries are termed the "short name space". The names contained in the set of all long directory entries are termed the "long name space". Together, they form a single unified name space in which no duplicate names can exist. That is: any name within a specific directory, whether it is a short name or a long name, can occur only once in the name space. Furthermore, although the case of a name is preserved in a long name, no two names can have the same name although the names on the media actually differ by case. That is names like "foobar" cannot be created if there is already a short entry with a name of "FOOBAR" or a long name with a name of "FooBar".

All types of search operations within the file system (i.e. find, open, create, delete, rename) are case-insensitive. An open of "FOOBAR" will open either "FooBar" or "foobar" if one or the other exists. A find using "FOOBAR" as a pattern will find the same files mentioned. The same rules are also true for extended characters that are accented.

A short name search operation checks only the names of the short directory entries for a match. A long name search operation checks both the long and short directory entries. As the file system traverses a directory, it caches the long-name sub-components contained in long directory entries. As soon as a short directory entry is encountered that is associated with the cached long name, the long name search operation will check the cached long name first and then the short name for a match.

When a character on the media, whether it is stored in the OEM character set or in UNICODE, cannot be translated into the appropriate character in the OEM or ANSI code page, it is always "translated" to the "_" (underscore) character as it is returned to the user – it is NOT modified on the disk. This character is the same in all OEM code pages and ANSI.

Naming Conventions and Long Names
An API allows the caller to specify the long name to be assigned to a file or directory. They do not allow the caller to independently specify the short name. The reason for this prohibition is that the short and long names are considered to be a single unified name space. As should be obvious the file system's name space does not support duplicate names. In other words, a long name for a file may not contain the same name, ignoring case, as the short name in a different file. This restriction is intended to prevent confusion among users, and applications, regarding the proper name of a file or directory. To make this restriction transparent, whenever a long name is created and the no matching long name exists, the short name is automatically generated from the long name in such a way that it does not collide with an existing short name.

The technique chosen to auto-generate short names from long names is modeled after Windows NT. Auto-generated short names are composed of the basis-name and an optional numeric-tail.

The Basis-Name Generation Algorithm

The basis-name generation algorithm is outlined below. This is a sample algorithm and serves to illustrate how short names can be auto-generated from long names. An implementation should follow this basic sequence of steps.

1. The UNICODE name passed to the file system is converted to upper case.
2. The upper cased UNICODE name is converted to OEM.if (the uppercased UNICODE glyph does not exist as an OEM glyph in the OEM code page) or (the OEM glyph is invalid in an 8.3 name){ Replace the glyph to an OEM '_' (underscore) character. Set a "lossy conversion" flag.}
3. Strip all leading and embedded spaces from the long name.
4. Strip all leading periods from the long name.
5. While (not at end of the long name) and (char is not a period) and (total chars copied < 8){ Copy characters into primary portion of the basis name}
6. Insert a dot at the end of the primary components of the basis-name iff the basis name has an extension after the last period in the name.
7. Scan for the last embedded period in the long name.If (the last embedded period was found){ While (not at end of the long name) and (total chars copied < 3) { Copy characters into extension portion of the basis name }}
Proceed to numeric-tail generation.

The Numeric-Tail Generation Algorithm

If (a "lossy conversion" was not flagged) and (the long name fits within the 8.3 naming conventions) and (the basis-name does not collide with any existing short name){ The short name is only the basis-name without the numeric tail.}else{ Insert a numeric-tail "~n" to the end of the primary name such that the value of the "~n" is chosen so that the name thus formed does not collide with any existing short name and that the primary name does not exceed eight characters in length.}
The "~n" string can range from "~1" to "~999999". The number "n" is chosen so that it is the next number in a sequence of files with similar basis-names. For example, assume the following short names existed: LETTER~1.DOC and LETTER~2.DOC. As expected, the next auto-generated name of name of this type would be LETTER~3.DOC. Assume the following short names existed: LETTER~1.DOC, LETTER~3.DOC. Again, the next auto-generated name of name of this type would be LETTER~2.DOC. However, one absolutely cannot count on this behavior. In a directory with a very large mix of names of this type, the selection algorithm is optimized for speed and may select another "n" based on the characteristics of short names that end in "~n" and have similar leading name patterns.
Effect of Long Directory Entries on Down Level Versions of FAT
The support of long names is most important on the hard disk, however it will be supported on removable media as well. The implementation provides support for long names without breaking compatibility with the existing FAT format. A disk can be read by a down level system without any compatibility problems. An existing disk does not go through a conversion process before it can start using long names. All of the current files remain unmodified. The long name directory entries are added when a long name is created. The addition of a long name to an existing file may require the 8.3 directory entry to be moved if the required adjacent directory entries are not available.

The long name entries are as hidden as hidden or system files are on a down level system. This is enough to keep the casual user from causing problems. The user can copy the files off using the 8.3 name, and put new files on without any side effects

The interesting part of this is what happens when the disk is taken to a down level FAT system and the directory is changed. This can affect the long name entries since the down level system ignores these long names and will not ensure they are properly associated with the 8.3 names.

A down level system will only see the long name entries when searching for a label. On a down level system, the volume label will be incorrectly reported if the true volume label does not come before all of the long name entries in the root directory. This is because the long name entries also have the volume label bit set. This is unfortunate, but is not a critical problem.

If an attempt is made to remove the volume label, one of the long name directory entries may be deleted. This would be a rare occurrence. It is easily detected on an aware system. The long name entry will no longer be a valid file entry, since one or more of the long entries is marked as deleted. If the deleted entry is reused, then the attribute byte will not have the proper value for a long name entry.

If a file is renamed on a down level system, then only the short name will be renamed. The long name will not be affected. Since the long and short names must be kept consistent across the name space, it is desirable to have the long name become invalid as a result of this rename. The checksum of the 8.3 name that is kept in the long name directory provides the ability to detect this type of change. This checksum will be checked to validate the long name before it is used. Rename will cause problems only if the renamed 8.3 file name happens to have the same checksum. The checksum algorithm chosen has a relatively flat distribution across the short name space.

This rename of the 8.3 name must also not conflict with any of the long names. Otherwise a down level system could create a short name in one file that matches a long name, when case is ignored, in a different file. To prevent this, the automatic creation of an 8.3 name from a long name, that has an 8.3 format, will directly map the long name to the 8.3 name by converting the characters to upper case.

If the file is deleted, then the long name is simply orphaned. If a new file is created, the long name may be incorrectly associated with the new file name. As in the case of a rename the checksum of the 8.3 name will help prevent this incorrect association.

Validating The Contents of a Directory
These guidelines are provided so that disk maintenance utilities can verify individual directory entries for 'correctness' while maintaining compatibility with future enhancements to the directory structure.

1. DO NOT look at the content of directory entry fields marked 'reserved' and assume that, if they are any value other than zero, that they are 'bad'.
2. DO NOT reset the content of directory entry fields marked reserved to zero when they contain non-zero values (under the assumption that they are "bad"). Directory entry fields are designated reserved, rather than must-be-zero. They should be ignored by your application.. These fields are intended for future extensions of the file system. By ignoring them an utility can continue to run on future versions of the operating system.
3. DO use the A_LONG attribute first when determining whether a directory entry is a long directory entry or a short directory entry. The following algorithm is the correct algorithm for making this determination:

if (((LDIR_attr & ATTR_LONG_NAME_MASK) == ATTR_LONG_NAME) && (LDIR_Ord != 0xE5)){/* Found an active long name sub-component. */}

4. DO use bits 4 and 3 of a short entry together when determining what type of short directory entry is being inspected. The following algorithm is the correct algorithm for making this determination:

if (((LDIR_attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (LDIR_Ord != 0xE5)){if ((DIR_Attr & (ATTR_DIRECTORY ATTR_VOLUME_ID)) == 0x00) /* Found a file. */else if ((DIR_Attr & (ATTR_DIRECTORY ATTR_VOLUME_ID)) == ATTR_DIRECTORY) /* Found a directory. */else if ((DIR_Attr & (ATTR_DIRECTORY ATTR_VOLUME_ID)) == ATTR_VOLUME_ID) /* Found a volume label. */else /* Found an invalid directory entry. */}

5. DO NOT assume that a non-zero value in the "type" field indicates a bad directory entry. Do not force the "type" field to zero.
6. Use the "checksum" field as a value to validate the directory entry. The "first cluster" field is currently being set to zero, though this might change in future.

Other Notes Relating to FAT Directories
· Long File Name directory entries are identical on all FAT types. See the preceeding sections for details.

· DIR_FileSize is a 32-bit field. For FAT32 volumes, your FAT file system driver must not allow a cluster chain to be created that is longer than 0x100000000 bytes, and the last byte of the last cluster in a chain that long cannot be allocated to the file. This must be done so that no file has a file size > 0xFFFFFFFF bytes. This is a fundamental limit of all FAT file systems. The maximum allowed file size on a FAT volume is 0xFFFFFFFF (4,294,967,295) bytes.

· Similarly, a FAT file system driver must not allow a directory (a file that is actually a container for other files) to be larger than 65,536 * 32 (2,097,152) bytes. NOTE: This limit does not apply to the number of files in the directory. This limit is on the size of the directory itself and has nothing to do with the content of the directory. There are two reasons for this limit:

1. Because FAT directories are not sorted or indexed, it is a bad idea to create huge directories; otherwise, operations like creating a new entry (which requires every allocated directory entry to be checked to verify that the name doesn’t already exist in the directory) become very slow.
2. There are many FAT file system drivers and disk utilities, including Microsoft’s, that expect to be able to count the entries in a directory using a 16-bit WORD variable. For this reason, directories cannot have more than 16-bits worth of entries.