更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
mtd_partition.c 文件参考

浏览源代码.

函数

static VOID YaffsLockInit (VOID)
 
partition_paramGetSpinorPartParam (VOID)
 
mtd_partitionGetSpinorPartitionHead (VOID)
 
static VOID MtdNandParamAssign (partition_param *nandParam, const struct MtdDev *nandMtd)
 
static VOID MtdDeinitNandParam (VOID)
 反初始化 更多...
 
static partition_paramMtdInitNandParam (partition_param *nandParam)
 nand flash 初始化 更多...
 
static VOID MtdNorParamAssign (partition_param *spinorParam, const struct MtdDev *spinorMtd)
 nor flash 初始化,本函数只会被调用一次 更多...
 
static VOID MtdDeinitSpinorParam (VOID)
 
static partition_paramMtdInitSpinorParam (partition_param *spinorParam)
 spi nor flash 参数初始化 更多...
 
static INT32 MtdInitFsparParam (const CHAR *type, partition_param **fsparParam)
 根据 flash-type 来初始化分区的参数, Fspar 是不是 flash partition 的意思? 这名字取得有点费解 @note_thinking 更多...
 
static INT32 MtdDeinitFsparParam (const CHAR *type)
 根据flash-type 去初始化 分区的参数。 更多...
 
static INT32 AddParamCheck (UINT32 startAddr, const partition_param *param, UINT32 partitionNum, UINT32 length)
 增加MTD分区参数检查 更多...
 
static INT32 BlockDriverRegisterOperate (mtd_partition *newNode, const partition_param *param, UINT32 partitionNum)
 注册块设备,此函数之后设备将支持VFS访问 更多...
 
static INT32 CharDriverRegisterOperate (mtd_partition *newNode, const partition_param *param, UINT32 partitionNum)
 注册字符设备,此函数之后设备将支持VFS访问 更多...
 
static INT32 BlockDriverUnregister (mtd_partition *node)
 注销块设备驱动 更多...
 
static INT32 CharDriverUnregister (mtd_partition *node)
 注销字符设备驱动 更多...
 
INT32 add_mtd_partition (const CHAR *type, UINT32 startAddr, UINT32 length, UINT32 partitionNum)
 Add a partition. 更多...
 
static INT32 DeleteParamCheck (UINT32 partitionNum, const CHAR *type, partition_param **param)
 检查分区参数 更多...
 
static INT32 DeletePartitionUnregister (mtd_partition *node)
 删除分区驱动程序,注意每个分区的文件系统都可以不一样,驱动程序也都不同 更多...
 
static INT32 OsNodeGet (mtd_partition **node, UINT32 partitionNum, const partition_param *param)
 获取分区链表节点 更多...
 
static INT32 OsResourceRelease (mtd_partition *node, const CHAR *type, partition_param *param)
 释放分区链表节点所占内存 sizeof(mtd_partition) 更多...
 
INT32 delete_mtd_partition (UINT32 partitionNum, const CHAR *type)
 删除MTD分区 更多...
 

变量

pthread_mutex_t g_mtdPartitionLock = PTHREAD_MUTEX_INITIALIZER
 

函数说明

◆ AddParamCheck()

static INT32 AddParamCheck ( UINT32  startAddr,
const partition_param param,
UINT32  partitionNum,
UINT32  length 
)
static

增加MTD分区参数检查

在文件 mtd_partition.c245 行定义.

249{
250 UINT32 startBlk, endBlk;
251 mtd_partition *node = NULL;
252 if ((param->blockname == NULL) && (param->charname == NULL)) {//块/字符设备名称至少有一个
253 return -EINVAL;
254 }
255
256 if ((length == 0) || (length < param->block_size) ||
257 (((UINT64)(startAddr) + length) > param->flash_mtd->size)) {
258 return -EINVAL;
259 }
260
261 ALIGN_ASSIGN(length, startAddr, startBlk, endBlk, param->block_size);
262
263 if (startBlk > endBlk) {
264 return -EINVAL;
265 }
266 LOS_DL_LIST_FOR_EACH_ENTRY(node, &param->partition_head->node_info, mtd_partition, node_info) {//遍历分区节点
267 if ((node->start_block != 0) && (node->patitionnum == partitionNum)) {
268 return -EINVAL;
269 }
270 if ((startBlk > node->end_block) || (endBlk < node->start_block)) {
271 continue;
272 }
273 return -EINVAL;
274 }
275
276 return ENOERR;
277}
long unsigned int UINT64
Definition: los_typedef.h:66
unsigned int UINT32
Definition: los_typedef.h:57
UINT64 size
Definition: mtd_dev.h:80
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
UINT32 patitionnum
分区编号
UINT32 end_block
结束块索引
UINT32 start_block
开始块索引
LOS_DL_LIST node_info
双循环节点,挂在首个分区节点上
CHAR * blockname
块设备名称
CHAR * charname
字符设备名称
mtd_partition * partition_head
首个分区,其他分区都挂在.node_info节点上
struct MtdDev * flash_mtd
flash设备描述符,属于硬件驱动层
UINT32 block_size
块单位(4K),对文件系统而言是按块读取数据,方便和内存页置换
这是这个函数的调用关系图:

◆ BlockDriverRegisterOperate()

static INT32 BlockDriverRegisterOperate ( mtd_partition newNode,
const partition_param param,
UINT32  partitionNum 
)
static

注册块设备,此函数之后设备将支持VFS访问

在文件 mtd_partition.c279 行定义.

282{
283 INT32 ret;
284 size_t driverNameSize;
285
286 if (param->blockname != NULL) {
287 driverNameSize = strlen(param->blockname) + DRIVER_NAME_ADD_SIZE; // 设备名称长度增加3个字节
288 newNode->blockdriver_name = (CHAR *)malloc(driverNameSize);
289 if (newNode->blockdriver_name == NULL) {
290 return -ENOMEM;
291 }
292
293 ret = snprintf_s(newNode->blockdriver_name, driverNameSize,
294 driverNameSize - 1, "%s%u", param->blockname, partitionNum);
295 if (ret < 0) {
296 free(newNode->blockdriver_name);
297 newNode->blockdriver_name = NULL;
298 return -ENAMETOOLONG;
299 }
300 //在伪文件系统中注册块驱动程序,对节点数据以块方式访问
301 ret = register_blockdriver(newNode->blockdriver_name, param->flash_ops,
302 RWE_RW_RW, newNode);
303 if (ret) {
304 free(newNode->blockdriver_name);
305 newNode->blockdriver_name = NULL;
306 PRINT_ERR("register blkdev partition error\n");
307 return ret;
308 }
309 } else {
310 newNode->blockdriver_name = NULL;
311 }
312 return ENOERR;
313}
signed int INT32
Definition: los_typedef.h:60
char CHAR
Definition: los_typedef.h:63
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
CHAR * blockdriver_name
块设备驱动名称 例如: /dev/spinorblk0p0
const struct block_operations * flash_ops
块方式的操作数据
函数调用图:
这是这个函数的调用关系图:

◆ BlockDriverUnregister()

static INT32 BlockDriverUnregister ( mtd_partition node)
static

注销块设备驱动

在文件 mtd_partition.c350 行定义.

351{
352 INT32 ret;
353
354 if (node->blockdriver_name != NULL) {
355 ret = unregister_blockdriver(node->blockdriver_name);
356 if (ret == -EBUSY) {
357 PRINT_ERR("unregister blkdev partition error:%d\n", ret);
358 return ret;
359 }
360 free(node->blockdriver_name);
361 node->blockdriver_name = NULL;
362 }
363 return ENOERR;
364}
函数调用图:
这是这个函数的调用关系图:

◆ CharDriverRegisterOperate()

static INT32 CharDriverRegisterOperate ( mtd_partition newNode,
const partition_param param,
UINT32  partitionNum 
)
static

注册字符设备,此函数之后设备将支持VFS访问

在文件 mtd_partition.c315 行定义.

318{
319 INT32 ret;
320 size_t driverNameSize;
321
322 if (param->charname != NULL) {
323 driverNameSize = strlen(param->charname) + DRIVER_NAME_ADD_SIZE;
324 newNode->chardriver_name = (CHAR *)malloc(driverNameSize);
325 if (newNode->chardriver_name == NULL) {
326 return -ENOMEM;
327 }
328
329 ret = snprintf_s(newNode->chardriver_name, driverNameSize,
330 driverNameSize - 1, "%s%u", param->charname, partitionNum);
331 if (ret < 0) {
332 free(newNode->chardriver_name);
333 newNode->chardriver_name = NULL;
334 return -ENAMETOOLONG;
335 }
336 //在伪文件系统中注册字符驱动程序,以字符设备的方式访问数据
337 ret = register_driver(newNode->chardriver_name, param->char_ops, RWE_RW_RW, newNode);
338 if (ret) {
339 PRINT_ERR("register chardev partition error\n");
340 free(newNode->chardriver_name);
341 newNode->chardriver_name = NULL;
342 return ret;
343 }
344 } else {
345 newNode->chardriver_name = NULL;
346 }
347 return ENOERR;
348}
CHAR * chardriver_name
字符设备驱动名称 例如: /dev/nandchr0p2
const struct file_operations_vfs * char_ops
字符方式的操作数据
函数调用图:
这是这个函数的调用关系图:

◆ CharDriverUnregister()

static INT32 CharDriverUnregister ( mtd_partition node)
static

注销字符设备驱动

在文件 mtd_partition.c366 行定义.

367{
368 INT32 ret;
369
370 if (node->chardriver_name != NULL) {
371 ret = unregister_driver(node->chardriver_name);
372 if (ret == -EBUSY) {
373 PRINT_ERR("unregister chardev partition error:%d\n", ret);
374 return ret;
375 }
376 free(node->chardriver_name);//名称占用的内核空间,所以必须释放.
377 node->chardriver_name = NULL;
378 }
379
380 return ENOERR;
381}
函数调用图:
这是这个函数的调用关系图:

◆ DeleteParamCheck()

static INT32 DeleteParamCheck ( UINT32  partitionNum,
const CHAR type,
partition_param **  param 
)
static

检查分区参数

在文件 mtd_partition.c456 行定义.

459{
460 if (strcmp(type, "nand") == 0) {
461 *param = g_nandPartParam;
462 } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) {
463 *param = g_spinorPartParam;
464 } else {
465 PRINT_ERR("type error \n");
466 return -EINVAL;
467 }
468
469 if ((partitionNum >= CONFIG_MTD_PATTITION_NUM) ||
470 ((*param) == NULL) || ((*param)->flash_mtd == NULL)) {
471 return -EINVAL;
472 }
473 return ENOERR;
474}
这是这个函数的调用关系图:

◆ DeletePartitionUnregister()

static INT32 DeletePartitionUnregister ( mtd_partition node)
static

删除分区驱动程序,注意每个分区的文件系统都可以不一样,驱动程序也都不同

在文件 mtd_partition.c476 行定义.

477{
478 INT32 ret;
479
480 ret = BlockDriverUnregister(node);//注销块设备驱动程序
481 if (ret == -EBUSY) {
482 return ret;
483 }
484
485 ret = CharDriverUnregister(node);//注销字符设备驱动程序
486 if (ret == -EBUSY) {
487 return ret;
488 }
489
490 return ENOERR;
491}
static INT32 BlockDriverUnregister(mtd_partition *node)
注销块设备驱动
static INT32 CharDriverUnregister(mtd_partition *node)
注销字符设备驱动
函数调用图:
这是这个函数的调用关系图:

◆ GetSpinorPartitionHead()

mtd_partition * GetSpinorPartitionHead ( VOID  )

在文件 mtd_partition.c86 行定义.

87{
88 return g_spinorPartitionHead;
89}

◆ GetSpinorPartParam()

partition_param * GetSpinorPartParam ( VOID  )

在文件 mtd_partition.c81 行定义.

82{
83 return g_spinorPartParam;
84}
这是这个函数的调用关系图:

◆ MtdDeinitFsparParam()

static INT32 MtdDeinitFsparParam ( const CHAR type)
static

根据flash-type 去初始化 分区的参数。

在文件 mtd_partition.c230 行定义.

231{
232 if (strcmp(type, "nand") == 0) {
233 MtdDeinitNandParam();//去初始化(析构) Nand flash 参数
234 g_nandPartParam = NULL;
235 } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) {
236 MtdDeinitSpinorParam();//去初始化(析构) Nor flash 参数, 注 : .h 文件有 spi 和 cfi 的区别介绍
237 g_spinorPartParam = NULL;
238 } else {
239 return -EINVAL;
240 }
241
242 return ENOERR;
243}
static VOID MtdDeinitSpinorParam(VOID)
static VOID MtdDeinitNandParam(VOID)
反初始化
函数调用图:
这是这个函数的调用关系图:

◆ MtdDeinitNandParam()

static VOID MtdDeinitNandParam ( VOID  )
static

反初始化

在文件 mtd_partition.c108 行定义.

109{
110 if (YaffsLockDeinit != NULL) {
111 YaffsLockDeinit();
112 }
113}
这是这个函数的调用关系图:

◆ MtdDeinitSpinorParam()

static VOID MtdDeinitSpinorParam ( VOID  )
static

在文件 mtd_partition.c166 行定义.

167{
168 if (Jffs2LockDeinit != NULL) {
169 Jffs2LockDeinit();
170 }
171}
这是这个函数的调用关系图:

◆ MtdInitFsparParam()

static INT32 MtdInitFsparParam ( const CHAR type,
partition_param **  fsparParam 
)
static

根据 flash-type 来初始化分区的参数, Fspar 是不是 flash partition 的意思? 这名字取得有点费解 @note_thinking

在文件 mtd_partition.c210 行定义.

211{
212 if (strcmp(type, "nand") == 0) {// nand flash 的处理
213 g_nandPartParam = MtdInitNandParam(g_nandPartParam);//初始化全局变量
214 *fsparParam = g_nandPartParam;//参数接走全局变量
215 } else if (strcmp(type, "spinor") == 0 || strcmp(type, "cfi-flash") == 0) { //nor flash的处理
216 g_spinorPartParam = MtdInitSpinorParam(g_spinorPartParam);//初始化全局变量
217 *fsparParam = g_spinorPartParam;//参数接走全局变量
218 } else {
219 return -EINVAL;
220 }
221
222 if ((*fsparParam == NULL) || ((VOID *)((*fsparParam)->flash_mtd) == NULL)) {
223 return -ENODEV;
224 }
225
226 return ENOERR;
227}
static partition_param * MtdInitSpinorParam(partition_param *spinorParam)
spi nor flash 参数初始化
static partition_param * MtdInitNandParam(partition_param *nandParam)
nand flash 初始化
函数调用图:
这是这个函数的调用关系图:

◆ MtdInitNandParam()

static partition_param * MtdInitNandParam ( partition_param nandParam)
static

nand flash 初始化

在文件 mtd_partition.c115 行定义.

116{
117 struct MtdDev *nandMtd = GetMtd("nand");
118 if (nandMtd == NULL) {
119 return NULL;
120 }
121 if (nandParam == NULL) {
122 if (YaffsLockInit != NULL) {
123 YaffsLockInit(); //加锁
124 }
125 nandParam = (partition_param *)zalloc(sizeof(partition_param));
126 if (nandParam == NULL) {
128 return NULL;
129 }
130 g_nandPartitionHead = (mtd_partition *)zalloc(sizeof(mtd_partition));
131 if (g_nandPartitionHead == NULL) {
133 free(nandParam);
134 return NULL;
135 }
136
137 MtdNandParamAssign(nandParam, nandMtd);
138 }
139
140 return nandParam;
141}
void * zalloc(size_t size)
Definition: malloc.c:91
void * GetMtd(const char *type)
static VOID YaffsLockInit(VOID)
Definition: mtd_partition.c:64
static VOID MtdNandParamAssign(partition_param *nandParam, const struct MtdDev *nandMtd)
Definition: mtd_partition.c:92
flash MTD 层 描述符
Definition: mtd_dev.h:76
分区参数描述符,一个分区既可支持按块访问也可以支持按字符访问,只要有驱动程序就阔以
函数调用图:
这是这个函数的调用关系图:

◆ MtdInitSpinorParam()

static partition_param * MtdInitSpinorParam ( partition_param spinorParam)
static

spi nor flash 参数初始化

在文件 mtd_partition.c173 行定义.

174{
175#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7 //
176 struct MtdDev *spinorMtd = GetMtd("spinor");
177#else
178 struct MtdDev *spinorMtd = GetCfiMtdDev();
179#endif
180 if (spinorMtd == NULL) {
181 return NULL;
182 }
183 if (spinorParam == NULL) {
184 if (Jffs2LockInit != NULL) {
185 if (Jffs2LockInit() != 0) { /* create jffs2 lock failed */
186 return NULL;
187 }
188 }
189 spinorParam = (partition_param *)zalloc(sizeof(partition_param));
190 if (spinorParam == NULL) {
191 PRINT_ERR("%s, partition_param malloc failed\n", __FUNCTION__);
193 return NULL;
194 }
195 g_spinorPartitionHead = (mtd_partition *)zalloc(sizeof(mtd_partition));
196 if (g_spinorPartitionHead == NULL) {
197 PRINT_ERR("%s, mtd_partition malloc failed\n", __FUNCTION__);
199 free(spinorParam);
200 return NULL;
201 }
202
203 MtdNorParamAssign(spinorParam, spinorMtd);
204 }
205
206 return spinorParam;
207}
static VOID MtdNorParamAssign(partition_param *spinorParam, const struct MtdDev *spinorMtd)
nor flash 初始化,本函数只会被调用一次
函数调用图:
这是这个函数的调用关系图:

◆ MtdNandParamAssign()

static VOID MtdNandParamAssign ( partition_param nandParam,
const struct MtdDev nandMtd 
)
static

在文件 mtd_partition.c92 行定义.

93{
94 LOS_ListInit(&g_nandPartitionHead->node_info);//初始化全局链表
95 /*
96 * If the user do not want to use block mtd or char mtd ,
97 * you can change the NANDBLK_NAME or NANDCHR_NAME to NULL.
98 */
99 nandParam->flash_mtd = (struct MtdDev *)nandMtd;
100 nandParam->flash_ops = GetDevNandOps(); //获取块设备操作方法
101 nandParam->char_ops = GetMtdCharFops(); //获取字符设备操作方法
102 nandParam->blockname = NANDBLK_NAME; // /dev/nandblk
103 nandParam->charname = NANDCHR_NAME; // /dev/nandchr
104 nandParam->partition_head = g_nandPartitionHead;//头分区节点
105 nandParam->block_size = nandMtd->eraseSize;//4K
106}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
UINT32 eraseSize
4K, 跟PAGE_CACHE_SIZE对应
Definition: mtd_dev.h:81
函数调用图:
这是这个函数的调用关系图:

◆ MtdNorParamAssign()

static VOID MtdNorParamAssign ( partition_param spinorParam,
const struct MtdDev spinorMtd 
)
static

nor flash 初始化,本函数只会被调用一次

在文件 mtd_partition.c143 行定义.

144{
145 LOS_ListInit(&g_spinorPartitionHead->node_info);//初始化全局链表,所有spi nor 分区节点都将挂上来
146 /*
147 * If the user do not want to use block mtd or char mtd ,
148 * you can change the SPIBLK_NAME or SPICHR_NAME to NULL.
149 *///如果用户不想使用 block mtd 或 char mtd ,您可以将 SPIBLK_NAME 或 SPICHR_NAME 更改为 NULL。
150 spinorParam->flash_mtd = (struct MtdDev *)spinorMtd;
151#ifndef LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7 //QEMU开关
152 spinorParam->flash_ops = GetDevSpinorOps();//块操作
153 spinorParam->char_ops = GetMtdCharFops();//字符操作
154 spinorParam->blockname = SPIBLK_NAME;
155 spinorParam->charname = SPICHR_NAME;
156#else
157 spinorParam->flash_ops = GetCfiBlkOps();
158 spinorParam->char_ops = NULL;
159 spinorParam->blockname = CFI_DRIVER;
160 spinorParam->charname = NULL;
161#endif
162 spinorParam->partition_head = g_spinorPartitionHead;//头分区节点
163 spinorParam->block_size = spinorMtd->eraseSize;//4K, 读/写/擦除 的最小单位
164}
函数调用图:
这是这个函数的调用关系图:

◆ OsNodeGet()

static INT32 OsNodeGet ( mtd_partition **  node,
UINT32  partitionNum,
const partition_param param 
)
static

获取分区链表节点

在文件 mtd_partition.c493 行定义.

494{ //遍历链表
495 LOS_DL_LIST_FOR_EACH_ENTRY(*node, &param->partition_head->node_info, mtd_partition, node_info) {
496 if ((*node)->patitionnum == partitionNum) {//找到分区ID
497 break;
498 }
499 }
500 if ((*node == NULL) || ((*node)->patitionnum != partitionNum) ||
501 ((*node)->mountpoint_name != NULL)) {
502 return -EINVAL;
503 }
504
505 return ENOERR;
506}
这是这个函数的调用关系图:

◆ OsResourceRelease()

static INT32 OsResourceRelease ( mtd_partition node,
const CHAR type,
partition_param param 
)
static

释放分区链表节点所占内存 sizeof(mtd_partition)

在文件 mtd_partition.c508 行定义.

509{
510 (VOID)LOS_MuxDestroy(&node->lock);
511 LOS_ListDelete(&node->node_info);//将自己摘掉
512 (VOID)memset_s(node, sizeof(mtd_partition), 0, sizeof(mtd_partition));
513 free(node);
514 (VOID)FreeMtd(param->flash_mtd);//释放MTD
515 if (LOS_ListEmpty(&param->partition_head->node_info)) {//如果是最后一个
516 free(param->partition_head);//释放头节点内存
517 param->partition_head = NULL;
518 free(param);
519
520 if (MtdDeinitFsparParam(type) != ENOERR) {
521 return -EINVAL;
522 }
523 }
524 return ENOERR;
525}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
销毁互斥锁
Definition: los_mux.c:289
int FreeMtd(struct MtdDev *mtd)
static INT32 MtdDeinitFsparParam(const CHAR *type)
根据flash-type 去初始化 分区的参数。
struct mtd_node mtd_partition
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
LosMux lock
每个分区都有自己的互斥锁
函数调用图:
这是这个函数的调用关系图:

◆ YaffsLockInit()

static VOID YaffsLockInit ( VOID  )
static

在文件 mtd_partition.c64 行定义.

77{
78 return g_nandPartParam;
79}
这是这个函数的调用关系图:

变量说明

◆ g_mtdPartitionLock

pthread_mutex_t g_mtdPartitionLock = PTHREAD_MUTEX_INITIALIZER

在文件 mtd_partition.c48 行定义.