现在的位置: 首页 > 综合 > 正文

mtd -flash函数说明

2017年12月22日 ⁄ 综合 ⁄ 共 2484字 ⁄ 字号 评论关闭

 

在这里主要描述
v3

mtd
,在
linux

MTD
子系统当中:

 
Linux MTD
设备的
NOR
 
Flash
芯片驱动遵循
CFI
接口标准,其驱动程序位于
drivers/mtd/chips
子目录下。
NAND

Flash
的驱动程序则位于
/drivers/mtd/nand
子目录下Map
中的
bankwidth
是总线位宽,
device_type
是芯片位宽;读写,要按照总线位宽读写1
:读写,要按照总线位宽读写,注意不是
FLASH
芯片位宽(例如背靠背)。2
:寻址,程序要访问的地址和
FLASH
芯片地址引脚得到的值是不一样的,例如
16
位的
FLASH
芯片,对于
CPU

0x00

0x01
表示2
个不同的字节,但是到了
FLASH
引脚得到的都是
0
,也就是都指向
FLASH
的第一个
WORD
。可以认为地址总线的
bit0
悬空,或者认为转换总线
, bit0
上实际输出的是
bit1
。这个解释了要点
1
。3
:芯片手册提到偏移量都是基于
WORD
的,而
WORD
的位宽取决于芯片的位宽,因此在下命令的时候,实际偏移
=
手册偏移*buswidth/8 。4
:芯片手册提到的变量长度(典型如
CFI
信息)例如
2
,指的是,变量是个
16bit
数,但是读的时候,要读
2

WORD
,然后把每个WORD
的低
8
位拼成
1

16bit
数。读
WORD
再拼凑确实挺麻烦,尤其是读取大结构的时候,不过参照
cfi_util.c

cfi_read_pri
函数的做法就简单了。5
:背靠背,也就是比方说
2

16
位的芯片一起接在
32
位的总线上。带来的就是寻址的问题,很显然,首先要按
32
位读写;其次就是下命令的地址,实际偏移
=
手册偏移
*interleave*device_type/8
,device_type=buswidth/interleave
,而
buswidth
这个时候是
32(总线位宽
)
。另外就是背靠背的时候,命令和返回的状态码是“双份的”,例如
2

16
位背靠背,读命令是
0x00ff00ff

系统在启动的时候会在main.c
中的
init—

do_basic_setup-

do_initcalls();这里他会先执行
cfi_probe_init
函数,在
chip_drvs_list
链表中增加了
cfi
接口标准的硬件驱动:static struct mtd_chip_driver cfi_chipdrv =
{

      
probe:
cfi_probe,

      
name:
"cfi_probe",

      
module:
THIS_MODULE

};同样也执行
cfi_amdstd_init
函数static struct mtd_chip_driver
amd_flash_chipdrv = {

      
probe:
amd_flash_probe,

      
destroy:
amd_flash_destroy,

      
name:
"amd_flash",

      
module:
THIS_MODULE

};
 
以前的理解有问题,下面是两种命令集,一个是
amd/fujistu
,一个是
inter/sharp

static struct mtd_chip_driver
cfi_intelext_chipdrv = {

      
probe:
NULL, /* Not usable directly */

      
destroy:
cfi_intelext_destroy,

      
name:
"cfi_cmdset_0001",

      
module:
THIS_MODULE

};static struct mtd_chip_driver
cfi_amdstd_chipdrv = {

      
probe:
NULL, /* Not usable directly */

      
destroy:
cfi_amdstd_destroy,

      
name:
"cfi_cmdset_0002",

      
module:
THIS_MODULE

};我们可以看出,因为
cfi
标准是
intel
出的,所以在他的
probe
里面都可以通用
chip_drvs_list
。在我们的
code
中,支持了
cfi
,(要么是cfi,要么非
cfi

NAND
型),我自己个人认为
cfi_probe_init
设置去检测系统中用的是
cfi
,然后又要支持
flash
新片的高级选项,比如芯片位宽等等一些参数,应该是给
cfi_probe_init
的参数吧。这里会运行那些静态编译到内核中的模块,在这里是:
avalanche_mtd_init
,在该函数里面:avalanche_mtd_info
= do_map_probe("cfi_probe", &avalanche_map);在这里我们会找到通用的
cfi
驱动(在这里,我自己认为还有很多改进的地方)接着会调用:cfi_probe –
》mtd_do_chip_probe---
》genprobe_ident_chips-

genprobe_new_chip(在这个函数里面会检查该芯片是否为
cfi
接口标准的,其中通过的方式是:向
flash
的几个端口写几个字节,然后在特定的端口去读,看是否为
qry
,如果是,就是
cfi
接口标准,函数调用如下:

cfi_send_gen_cmd(0xF0, 0, base, map, cfi,
cfi->device_type, NULL);

cfi_send_gen_cmd(0x98, 0x55, base, map,
cfi, cfi->device_type, NULL);

if (!qry_present(map,base,cfi))

             
return
0;

)在这里会填写
struct
cfi_private cfi;

map->fldrv_priv = cfi;

 ---

check_cmd_set
根句
cfi->cfiq->P_ID
或者
cfi->cfiq->A_ID
进行调用相关的函数,这里是cfi_cmdset_0002
函数

--

cfi_read_pri

--

      
cfi_fixup(map,
fixup_table);
函数

--

cfi_amdstd_setup
函数

抱歉!评论已关闭.